C++ でファイルから行を読み取るための推奨パターンは何ですか? 質問する

C++ でファイルから行を読み取るための推奨パターンは何ですか? 質問する

C++ チュートリアルでは、ファイルから行を読み取る方法が少なくとも 2 つ紹介されています。

std::ifstream fs("myfile.txt");
if (fs.is_open()) {
  while (fs.good()) {
    std::string line;
    std::getline(fs, line);
    // ...

そして:

std::ifstream fs("myfile.txt");
std::string line;
while (std::getline(fs, line)) {
  // ...

もちろん、ファイルが存在し、開かれていることを確認するためのチェックをいくつか追加できます。例外処理以外に、より詳細な最初のパターンを優先する理由はありますか? 標準的な方法は何ですか?

ベストアンサー1

while (std::getline(fs, line))
{}

これは正しいだけでなく、好ましい それは慣用表現だからです。

最初のケースでは、 asまたは同等のものfsの後にチェックしていないと思います。そうしないと、最初のケースは完全に間違っています。または、そうする場合でも、2 番目のケースの方が簡潔で論理が明確なので、依然として好ましいです。std::getline()if(!fs) break;

この機能をgood()使うべきであるストリームから読み取ろうとしました。これは、試行が成功したかどうかを確認するために使用されます。最初のケースでは、そうしません。 の後std::getline()、何が返されるかを確認することさえせずに、読み取りが成功したと想定しています。また、が true を返すfs.good()場合、 はストリームから行を正常に読み取ると想定しているようです。あなたはまったく逆の方向に進んでいます。実際は、 がストリームから行を正常に読み取る場合、は を返します。fs.good()std::getlinestd::getlinefs.good()true

cplusplusのドキュメントには、good()それ、

ストリームのエラー フラグ (eofbit、failbit、badbit) が設定されていない場合、関数は true を返します。

つまり、入力ストリームからデータを読み取ろうとしたときに、その試行が失敗した場合にのみ、失敗フラグが設定され、失敗を示す値としてgood()返されます。false

line変数のスコープをループ内のみに制限したい場合は、for次のようにループを記述します。

for(std::string line; std::getline(fs, line); )
{
   //use 'line'
}

注: この解決策は @john の解決策を読んだ後に思いついたものですが、彼のバージョンよりも優れていると思います。


2 番目の方法が好ましく、慣用的な理由については、ここで詳しく説明します。

または、@Jerry Coffin によるこの素晴らしいブログを読んでみてください:

おすすめ記事