私がこれを行う場合:
ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
cout << token;
else
cout << token;
2番目の場合の出力は空の文字列であることが保証されていますか?私はcplusplus.comでこれに対する答えを見つけることができないようです。
ありがとう!
私がこれを行う場合:
ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
cout << token;
else
cout << token;
2番目の場合の出力は空の文字列であることが保証されていますか?私はcplusplus.comでこれに対する答えを見つけることができないようです。
ありがとう!
2番目の場合の出力は空の文字列であることが保証されていますか?
答えは:いいえ、それは以下に説明するように依存するからです。
else
ブロックはストリームからの読み取りに失敗した場合にのみ実行されるため、読み取り中にいつでも発生する可能性があります。
最初の試行で失敗した場合、ストリームからの文字抽出は行われないため、 token
(以前のように)空になります。
数回の読み取り後に失敗した場合、token
空にはなりません。これには、ストリームからこれまでに正常に読み取られた文字が含まれます。
規格のセクション§21.3.7.9は次のように述べています。
kがtypenamebasic_istream:: セントリーk(is)によって構築されたかのように、歩哨オブジェクトkを構築することから始めます。bool(k)がtrueの場合、str.erase()を呼び出してから、isから文字を抽出し、str.append(1、c)を呼び出すかのようにそれらをstrに追加します。is.width()がゼロより大きい場合、追加される文字の最大数nはis.width();です。それ以外の場合、nはstr.max_size()です。次のいずれかが発生するまで、文字が抽出されて追加されます。
—n文字が格納されます。
—ファイルの終わりは入力シーケンスで発生します。
— isspace(c、is.getloc())は、次に使用可能な入力文字cに対してtrueです。
最後の文字(存在する場合)が抽出された後、is.width(0)が呼び出され、歩哨オブジェクトkが破棄されます。
関数が文字を抽出しない場合、is.setstate(ios :: failbit)を呼び出します。これにより、ios_base :: failure(27.4.4.3)がスローされる可能性があります。
また、標準のセクション§21.3.1/ 2は、デフォルトの構築された文字列が空になることを保証していることに注意してください。標準では、サイズはゼロ、つまり空になるとされています。
これをテストしたかったので、元の回答を削除しました。これは私が見ているものです。読み取り中にエラーが発生した場合(このコンテキストではEOFはカウントされません)、元の文字列が変更され、ブランチは変更されたバージョンを確認します。テストするために、私は次のことを行い、2Gbファイル(touch
then truncate
)を作成しました。上記のコードを読んでください。コードの実行中に、ファイルを削除しました(これにより、failbit
-が設定されるはずです)。すぐに読み取りを停止しますが、文字列が変更されます-サイズが大きくなります。
私にとってこれは、ストリーム操作が失敗した場合でも文字列が変更されることを示しています。
いいえ、操作が失敗した場合でも、文字列にはこれまでに抽出された文字が含まれます。
規格によると(§21.4.8.9):
効果:フォーマットされた入力関数として動作します(27.7.2.2.1)。オブジェクトを作成した後
sentry
、歩哨がtrueに変換された場合、を呼び出しstr.erase()
てから文字を抽出し、を呼び出すかのようis
にそれらを追加します。がゼロより大きい場合、追加される文字の最大数nは;です。それ以外の場合、nはです。次のいずれかが発生するまで、文字が抽出されて追加されます。 —n文字が格納されます。 —ファイルの終わりは入力シーケンスで発生します。 —次に使用可能な入力文字cに当てはまります。str
str.append(1,c)
is.width()
is.width()
str.max_size()
isspace(c,is.getloc())