2011-02-06 8 views
2

私は大きなファイルI/Oライブラリを構築していますが、現在はgetl​​ine()の相互運用性とファイルへの書き込みに苦しんでいます。私の質問はこのようなものですが、残念ながら未回答のまま残っています。C++ After I use getline to read from a file I can no longer write to the txt filegetlineの使用に続いて、ファイルに書き込めません

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

マイコードは以下のとおりです。私はフェイルビットが最初の書き込み試行の後に起動されていることに気づいた。しかし、getline()操作を削除してもアクティブではないため、この原因はわかりません。

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

いつものように、どんな助けもあります。

// 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 

答えて

3

を次の代わりに、

fstream workFile("testdoc.txt"); 

使用は、それが見えますファイルの最後にある。私はそれを正確に説明することはできませんが、それはあなたが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(); 
} 
+0

問題をテストする時間をとってくれてありがとう。 – BSchlinker

0

<<がファイルに何をするかを考えてみて:それはそれに書き込み、そしてあなたはそれから読み取ることができるので、我々はそれを追加するために開かれた知っています。 )ファイルにデータを書き込むと、ファイルオフセットはファイルの末尾にあるに自動的に格納されるため、これ以上読むことはありません。

さて、あなたはfstream::tellgのように、lseek(2)またはそれを包む方法を使用して、この周りのあなたの方法を書くことができますが、私はあなた本当にが望むものを賭けて、そのファイルにすべてを書き込み、出力のための一時ファイルを作成することです一時ファイルを元に戻すために移動します。

更新

申し訳ありませんが、それは後半だと私は質問の意味を逆転させました。まったく何も起こっていなければ、書き込み可能なファイルがない可能性があります。 failフラグを確認しましたか?

のfstream クラスのオブジェクトを構築します

:それは言うiostream::fstreamクラスのためのドキュメントを参照してください。これは、関連付けられたfilebufオブジェクトの初期化 と、 パラメータとしてfilebufオブジェクトを持つ 基本クラスのコンストラクタへの呼び出しを、 が呼び出すことを意味します。第 コンストラクタバージョンを使用する場合

また、 ストリームは、同じパラメータを持つ オープンメンバ関数の呼び出しが行われたかのように物理的 ファイルに関連付けられています。何のファイルが が失敗継承されたメンバーでチェックすることができ、ストリームのfailbitが設定されているストリームバッファと (に関連する ではありませんが、

コンストラクタは、ファイルを開くことで 成功しなかった場合は、オブジェクトは はまだ作成されています)。

+0

これは、ファイルが実際に書き込まれていた場合に当てはまります。しかし、そうではありません。上記のように、2番目の行は正常に読み込まれ、ファイルのオフセットは移動していないことが示されます。後でファイルの内容を確認すると、ファイルの内容は変更されていません。 – BSchlinker

+0

たとえば、ファイルに1行しかない場合は、 "getline()"を実行して次の行で出力操作を実行できるはずです。しかし、それは現在可能ではありません。ファイルは書き込まれません。 – BSchlinker

+0

ああ、申し訳ありません。ファイルがどのように開かれているかをポイントの感覚に逆転させます。私はあなたがファイルをまったく書くために開かないと思っています。 –

0

ファイルが最も可能性の高い出力用にオープンされていないので、<<オペレータはオフセット期待するようないくつかの実験に基づいて

fstream workFile("testdoc.txt", fstream::in | fstream::out); 
+0

fstreamはデフォルトでこれら2つの特性(http://www.cplusplus.com/doc/tutorial/files/)で開きます。しかし、私はこれを試して、残念ながらそれは問題を解決しません。 – BSchlinker

1

のfstreamだけが共有する1つのストリーム位置は、読み込みしており、書きます。だから、実際には、読み書きの間で変更するときにシークを行う必要があります。いずれかのtell関数を使用して、現在の読み取りまたは書き込み位置を保存し、次に続行するときに検索することができます。

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

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(); 
関連する問題