2012-01-20 7 views
18

にCOUTとwcoutをミキシング:は、私は次のコードを持っていた「C++クックブック」を読んでいた同じプログラム

// cout << s << std::endl; // You shouldn't be able to 
wcout << ws << std::endl;  // run these at the same time 

あなたは、実際の例を見ることに興味があるなら、ここにa link to the page on Google booksです。

また、私はこれを見つけました。これは、wcoutとcoutの混合が問題ないと言われています。SO question誰かがこのコメントが話していることを私に説明できますか? C++標準[27.4.1]から

EDIT

:ワイド対応狭文字ストリームの操作をミキシング

は、指定されたように、ファイルに対するそのような混合操作と同じセマンティクスを以下ISO C標準の改正1 C標準[7.19.2]から

各ストリームは、配向性を有します。ストリームが外部ファイルに関連付けられた後で、操作が実行される前に が実行されると、ストリームは方向がありません。広域文字入力/出力関数が方向なしでストリームに適用されると、ストリームはワイド・オリエンテッド・ストリームになります。同様に、バイト入出力関数が方向なしでストリームに適用されると、ストリームはバイト指向のストリームになります。 freopen関数またはfwide関数を呼び出すだけで、ストリームの方向を変更することができます。 freopenの呼び出しが成功すると、方向は削除されます。

バイト指向のストリームには、バイト入出力関数を適用してはならず、幅広のストリームには文字の入出力機能を適用してはなりません。

標準では、それらを混在させるべきではないと言われています。しかし、私はこの引用を見つけたfrom this article

fwide関数は実装されていないと文書化されています。実用的な観点からは、少なくとも出力行全体のレベルでは、明らかにcoutとwcoutの混在をうまく使っています。幸いなことに、Visual C++は明らかに標準の要件を無視し、明白ではない明示的なC FILEストリームの向きを維持しません。

そしてまた、GCCについて、私はhereから、この引用を見つけた:

これは、(新)機能ではなく、バグで、中に流れの向きについてのlibstdC++/11705および一般的な検索で を見ますC標準(C99,7.19.2)。簡単に言えば、 は、バイト指向とワイド指向の入出力を混在させることはできません。今のところバグ がlibstdC++/11705で指摘されているので、あなたは の期待値に近いものをstd :: ios :: sync_with_stdio(false)を呼び出して得ることができます。あなたのプログラム の冒頭にあります。

答えて

16

初めてcoutまたはwcoutが呼び出されると、stdoutの向きが設定されます。 coutの場合はstdoutがバイト指向のストリームとなり、wcoutの場合はstdoutがワイドなストリームになります。 C++標準[27.4.1]とC標準[7.19.2]によると、ストリームの方向が設定されたら、そのストリームの方向と互換性のない関数を呼び出さないでください。

2

私には分かりません。

スレッドを禁止すると、のいずれかの文が「同時に」2つの文を実行することはできません。あなたは確かにプログラムの異なる点で coutwcoutを使うことができます。どちらも STDOUTにマップされていますが、それは...ですが、バッファが違うと不安定になり、場合によっては予期しない発注になることがあります。

どうやら、それぞれが「宛先」ストリームSTDOUT配向をimbues、配向[C++11: 27.4.1][C99: 7.19.2]で吹き込まれたストリームの操作を混在することは許されません。

+0

実際に私は間違いかもしれないと思ったので、本の正誤表を確認しましたが、何も見つかりませんでした。 –

+0

@Jesse:著者に連絡する時間、たぶん。 –

+0

あなたは何を意味し、何が実際に起こるかを説明できますか?「どちらもSTDOUTにマップされていますか? 、ありがとう –

1

技術的には、ナローストリームとワイドストリームの両方を同時に使用できます。しかし、両方のキャラクタが同じ文字をエンコードするように手配しない限り、結果は乱れる可能性があります。これは、残念ながら、標準のストリームオブジェクトで使用されるエンコーディングを制御できないという注意点があります。少なくとも移植可能ではありません。エンコーディングが同じでも、部分文字が完全に書き込まれていることを確認する必要があります。つまり、少なくとも他の幅に切り替えるときにバッファをフラッシュする必要があります。

+0

標準でストリームに 'imbue'が定義されていないか、これをどのように解釈する必要がありますか? – Voo

+1

@Voo 'imbue()'は実際にはすべてのストリームオブジェクトに対して定義されています**。しかし、 'std :: codecvt <...>'を使うために必要なストリームバッファは 'std :: basic_filebuf <...>'です。しかし、標準ストリームオブジェクトは、この種のストリームバッファを使用する必要はありません。彼らは 'std :: basic_filebuf <...>'を使うかもしれませんが、私はそれを信じていません。実際には、私はこれについてC++ 2011の標準をチェックすべきです:それはC++ 2003では間違いありませんでしたが、変更されていないと思います。 –

+0

これは面白いです - 私はたったそれが正常に動作したファイルのために 'imbue'を使用しましたが、私は暗黙のうちにこれが標準のストリームオブジェクトでも動作することを期待していました。知っておいてください - しかし、最初に標準ストリームのためにそれを必要としなかった理由がありますので、実際には大きな問題ではありません。 – Voo

1

標準からの違反は、通常、未定義の動作の領域にあります。定義されていない動作は、一部の実装では正常に動作します。

0

推測すると、coutwcoutは2つの異なるストリームであり、ストリームの方向がどのように元のファイルの方向と相関するかについては何も言及していません。フードの下でストリームが静かに方向を変えることがありますか?stdout

関連する問題