2

大規模なファイル I/O ライブラリを構築していますが、現在 getline() とファイルへの書き込みの相互運用性に苦労しています。以下の私の質問は、残念ながら未回答のままです: C++ getline を使用してファイルから読み取ると、txt ファイルに書き込むことができなくなります。

getline() を使用すると、ファイルに書き込むことができなくなります。getline() を使用した読み取り要求は引き続き動作しますが、書き込み要求は失敗します。ただし、getline() の使用法をコメントアウトすると、書き込み操作は成功します。

私のコードは以下に掲載されています。最初の書き込み試行の後、failbit がアクティブになっていることに気付きました。ただし、getline() 操作を削除するとアクティブにならないため、これが発生する理由は不明です。

明確にする必要があります-既存のファイル(2行を含む)から完全に読み取ることができます。ただし、getline() ステートメントを削除しない限り、そのファイルに書き込むことはできません。

いつものように、どんな助けも感謝しています。

// Includes
#include <fstream>
#include <iostream>
#include <string>

// Namespace
using namespace std;

int main(){
    // filestream object
    fstream workFile("testdoc.txt"); //fstream uses ios::in | ios::out by default
    // note that I have tried including ios::in | ios::out to no avail

    // read from file
    string grabbedLine;
    getline(workFile, grabbedLine);
    cout << "Line #1: " << grabbedLine << endl;

    // write to file
    workFile<< "Here is some output (#1)" << endl;

    // read from file
    getline(workFile, grabbedLine);
    cout << "Line #2: " << grabbedLine << endl;

    // write to file
    workFile<< "Here is some output (#2)" << endl;

    // wait for some input...
    getchar();
}

Current console output (as expected from text file):
Line #1: This is line#1
Line #2: This is line#2
4

6 に答える 6

3

いくつかの実験に基づいて、<<オペレーターはオフセットがファイルの最後にあると予想しているようです。正確に説明することはできませんが、 を呼び出した後、オフセットが期待される場所にないようgetline()です。次の行を追加することで、ファイルへの書き込みを機能させることができました。

workFile.seekg(ios_base::end);

ファイルに書き込む直前。ただし、これはファイルの最後にオフセットを配置し、その後の 2 行目を正しく読み取れません。

あなたがやりたいことは、2 つのファイル ハンドルを開くことです。1 つは読み取り元、もう 1 つは書き込み先です。

int main(){
    // filestream object
    fstream workFileRead("testdoc.txt", ios_base::in);
    fstream workFileWrite("testdoc.txt" , ios_base::app | ios_base::out);

    // read from file
    string grabbedLine;
    getline(workFileRead, grabbedLine);
    cout << "Line #1: " << grabbedLine << endl;

    // write to file
    workFileWrite << "Here is some output (#1)" << endl;

    // read from file
    getline(workFileRead, grabbedLine);
    cout << "Line #2: " << grabbedLine << endl;

    // write to file
    workFileWrite<< "Here is some output (#2)" << endl;

    // wait for some input...
    getchar();
}
于 2011-02-06T04:47:36.553 に答える
2

これは古い投稿であることはわかっていますが、同じ問題に遭遇し、Google 検索でこの未回答の投稿にアクセスし続けました。...

私はこれを機能させることができました。リンクされた投稿で説明されているように、getline() を使用してファイルの最後まで読み取ると、Fail ビットが設定されます。これをクリアする必要があり、書き込みが成功する前に書き込みに適した場所にポインターが設定されます...たとえば、ファイルの最後の行を読み取ってから何かを書き込むコード:

fstream myfile;
char line[10];
string myText;

myfile.open("test.txt", ios::in | ios::out);
while ( myfile.getline(line,10) )
{  myText = line; }  //myText is left storing the last line

myfile.clear();
myfile.seekp(0, ios::end);
myfile << "Writing to this file!!!" << endl;
myfile.close();
于 2012-11-12T01:10:11.133 に答える
1

fstream には、読み取りと書き込みによって共有される 1 つのストリーム位置しかありません。したがって、実際には、読み取りと書き込みを切り替えるときにシークを行う必要があります。tell 関数の 1 つを使用して、現在の読み取りまたは書き込み位置を保存し、続行したいときに戻ってシークすることができます。

ファイルを 2 回開いて 2 つのストリーム位置を取得することは、おそらく良い考えではありません。OS でそれが許可されている場合、ファイルの内容がさまざまな方法で混同される可能性があります。

于 2011-02-06T10:18:52.047 に答える
0

ファイルは出力用に開かれていない可能性が最も高いため、代わりに

fstream workFile("testdoc.txt");

以下を使用

fstream workFile("testdoc.txt", fstream::in | fstream::out);
于 2011-02-06T04:30:51.423 に答える
0

ファイルに対して何が行われるかを考えてみましょう<<。ファイルは書き込みを行い、ファイルから読み取ることができるため、ファイルが追加のために開かれたことがわかります。)そうしないと、ファイルが最初に切り捨てられ、読み取りが成功しません。) データをファイルに書き込むと、ファイル オフセットは自動的にファイルの末尾に設定されるため、これ以上読み取るものはありません。

さて、lseek(2)またはそれをラップするメソッドを使用して、これを回避する方法を記述できますが、本当に必要なfstream::tellg、出力用の一時ファイルを作成し、すべてをそのファイルに書き込み、次に一時ファイルを元に戻して、元のファイルを置き換えます。

アップデート

申し訳ありませんが、遅くなり、質問の意味が逆になりました。何も起こらない場合は、書き込み用に開いているファイルがない可能性があります。fail旗は確認しましたか?iostream::fstreamクラスのドキュメントを参照してください。

fstream クラスのオブジェクトを構築します。これは、関連付けられた filebuf オブジェクトの初期化と、filebuf オブジェクトをパラメーターとして使用した基本クラスのコンストラクターの呼び出しを意味します。

さらに、2 番目のコンストラクター バージョンが使用されると、同じパラメーターでメンバー関数 open が呼び出されたかのように、ストリームが物理ファイルに関連付けられます。

コンストラクターがファイルを開くことに成功しなかった場合でも、オブジェクトは作成されますが、ファイルはストリーム バッファーに関連付けられておらず、ストリームの failbit が設定されています (継承されたメンバーの fail で確認できます)。

于 2011-02-06T04:21:20.243 に答える