2

次のC++プログラムについて考えてみます。このプログラムは、ファイルを受け取り、各行を出力します。これは、私が見たものに基づいて、後でファイルに追加する、より大きなプログラムのスライスです。

#include <fstream>
using std::fstream;
#include <iostream>
#include <string>
using std::string;

int main()
{
 fstream file("file.txt", fstream::in | fstream::out | fstream::app);

 string line;
 while (std::getline(file, line))
  std::cerr << line << std::endl;

 return 0;
}

次に、このバージョンのfile.txt(最初の行に1つの単語が続き、その後に改行が続く)を適用します。

Rain

私のマシン(Snow Leopard)では、これは何も出力しません。よく調べてみると、getlineへの最初の呼び出しは失敗します。不思議なことに、2行目を追加しても失敗します。それでも何も出力されません。

誰かがこの謎を解くことができますか?

4

2 に答える 2

9

あなたが言う時:

fstream file("file.txt", fstream::in | fstream::out | fstream::app);

ファイルを追加モードで開きます。つまり、最後に開きます。読み取りモードで開くだけです。

fstream file("file.txt", fstream::in );

またはifstreamを使用します。

ifstream file("file.txt" );

そしてもちろん、Earwickerが示唆しているように、オープンが成功したことを常にテストする必要があります。

追加モードで開くことにした場合は、読み取りポインタを明示的に移動できます。

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main() {
    fstream file( "afile.txt", ios::in | ios::out | ios::app );
    if ( ! file.is_open()  ) {
        cerr << "open failed" << endl;
        return 1;
    }
    else {
        file.seekg( 0, ios::beg );   // move read pointer
        string line;
        while( getline( file, line ) ) {
            cout << line << endl;
        }
    }
}

編集:ファイルを開くときに使用されるフラグの組み合わせは、実装固有の動作につながるようです。上記のコードは、Windowsではg ++で機能しますが、Linuxではg++では機能しません。

于 2010-02-21T10:00:16.317 に答える
2

ファイルが実際に開かれたかどうかを確認する必要があります。

if (!file)
    std::cerr << "Oh dear" << std::endl;

更新:実際、ファイルは開かれている可能性がありますが、追加モードになっています-Neiiの回答を参照してください。

更新2:わかりました、もう一度間違っています。少なくともLeopardのg++では、appフラグがフラグと互換性がないため、ファイルは開かれませんin。したがって、上記のチェックは印刷されますOh dear

MSVC ++では、先に進んでファイルを開きます。明らかに最初に読み取り位置があります。これは、他の人がそれが機能するのを見て、その信憑性を疑ったことをお詫びします。

于 2010-02-21T09:48:54.810 に答える