2

私は標準の C++ fstreams ライブラリを使用していますが、それを使用する正しい方法は何か疑問に思っています。経験から、私は小さな使用プロトコルをある程度理解しましたが、それについてはよくわかりません。簡単にするために、ファイルを読みたいだけだと仮定しましょう。たとえば、そのコンテンツをフィルタリングして別のファイルに置きます。私のルーティンはおおよそ次のとおりです。

  • istream i("filename")ファイルを開くローカル変数を宣言します。
  • ファイルが存在しないなどの理由で、開くときに問題が発生した場合に対処するために、i.good()またはをチェックします。i.is_open()その後、ファイルが存在し、私は大丈夫だと思います。
  • ファイルが空の場合を除外するためにi.peek()、もう一度呼び出します。その後、実際に読むものがあると思います。i.good()i.eof()
  • >>ファイルの内容を読み取り、終了したeof()ことを確認するために、またはその他のものを使用します。
  • 私はファイルを明示的に閉じません。私は RAII に依存し、メソッドをできる限り短く一貫したものにしています。

それは正気の (正しい、最小限の) ルーチンですか? 否定的な場合、どのように修正しますか? 私は人種を考慮していないことに注意してください- 同期は別の問題です.

4

2 に答える 2

4

peek/good/eof (3 番目のステップ) を排除します。単純にデータの読み取りを試行し、試行された読み取りが成功したか失敗したかを確認してください。同様に、4 番目のステップでは、試みた読み取りが成功したかどうかを確認します。

典型的なコードは次のようになります。

std::ifstream i("whatever");

if (!i)
    error("opening file");

while (i >> your_data)
    process(your_data);

if (!i.eof())
   // reading failed before end of file
于 2013-03-08T15:24:04.740 に答える
3

あなたが説明したよりも簡単です。最初の 2 つの手順は問題ありません (ただし、残りのアドバイスに従えば、2 番目の手順は必要ありません)。次に、抽出を試みる必要がありますが、抽出をループまたはifステートメントの条件として使用します。たとえば、ファイルがすべて同じ形式の一連の行 (またはその他の区切られたシーケンス) としてフォーマットされている場合、次のようにすることができます。

std::string line;
while (std::getline(i, line)) {
  // Parse line
}

ループの本体は、行抽出が機能する場合にのみ実行されます。もちろん、ループ内の行の有効性を確認する必要があります。

ストリームで特定の一連の抽出またはその他の操作を行う場合は、次のifような条件に配置できます。

if (i >> some_string &&
    i.get() == '-' &&
    i >> some_int) {
  // Use some_string and some_int
}

この最初の抽出が失敗した場合、 のi.ignore()短絡評価により は実行されません&&。ステートメントの本文は、if両方の抽出が成功した場合にのみ実行されます。2 つの抽出が一緒にある場合は、もちろんそれらを連鎖させることができます。

if (i >> some_string >> some_int) {
  // Use some_string and some_int
}

最初の抽出が失敗した場合、チェーンの 2 番目の抽出は行われません。抽出が失敗すると、ストリームは後続のすべての抽出も自動的に失敗する状態になります。

このため、ストリーム操作を条件の外に配置して、ストリームifの状態を確認することも問題ありません。

i >> some_string >> some_int;
if (i) {
  // Use some_string and some_int
}

どちらの方法でも、ストリームに関する特定の問題をチェックする必要はありません。ストリームをチェックしてeof()も、必ずしも次の読み取りが失敗するわけではありません。一般的なケースは、人々が次の誤った抽出ループを使用する場合です。

// DO NOT DO THIS
while (!i.eof()) {
  std::getline(i, line)
  // Do something with line
}

ほとんどのテキスト ファイルは、テキスト エディタが隠している余分な改行で終わります。テキスト ファイルから行を読み取っている場合、最後の反復では、読み取るファイルがまだあるため、まだファイルの終わりに達していません\n。そのため、ループが続き、存在しない次の行を抽出しようとして失敗します。多くの場合、これは「ファイルの最後の行を 2 回読む」と見なされます。

于 2013-03-08T15:23:28.857 に答える