2009-05-22 16 views
4

私に当たったパズル。単純なテストハーネスコードでは、stdoutにあまりにも多くの文字をストリームすると、プログラムは失敗します。奇妙だが非常に再現可能。これは、Windowsのみの問題かもしれないが、それは見て簡単です。coutストリームの制限?

#include <iostream> 
#include <deque> 

using namespace std; 

int main() 
{ 
    deque<char> d; 
    char c; 

    while (cin.get(c)) d.push_back(c); 

    for (deque<char>::reverse_iterator j = d.rbegin(); j != d.rend(); j++) 
    cout << (*j); 
} 

前のコードは、単に標準入力から文字のストリームをロードし、逆の順序でそれらを出力します。それは100Kかそれ以上の文字では正常に動作しますが、Windowsでは大きなファイルに対しては "stdoutを書き込むエラー"というメッセージが表示されてしまいます。それは常に同じキャラクターで死ぬ。 "cat bigfile.txt | reverse.exe"のようなシェルコマンドは、問題を再現するために必要なものです。 MSFTコンパイラとインテルコンパイラの両方が同様に動作します。

私はstdoutにバッファがあるかもしれないが、それが満たされたら自動的にフラッシュするべきではないことを認識していますか?

+1

私はあなたが実行しているコンパイラのバージョン、OS、およびメモリについてもっと詳しく説明する必要があると思います。私たちの少なくとも二人はこの問題を見ていません。 –

+0

また、 "reverse.exe

答えて

0

おかげで、 reverse.exeではなくcatコマンドが失敗している可能性があります。これはまさにそれだった.. reverse.exe < bigfile.txtはうまく動作するが、cat bigfile.txt | reverse.exeは "stdoutを書き込むエラー"で失敗します。 なぜCATが失敗するのかは謎ですが、少なくとも今は何か関連するコードではありません。

+3

これらの観測値をオリジナルの質問に編集として追加して、他の人が文脈でそれらを見ることができるようにすると、より便利です。あなたの「猫」はどこから来たのですか?私のものはCygwinのものです。 –

1

ここではそのような問題:

C:\Temp> cl 
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 

はEDIT:詳細

私はあなたが投稿したプログラムをコンパイルすることによって、これをテストしました。を100,000回繰り返したファイルを作成しました(サイズは1,000,000バイトです)。その後、私は何も問題はありませんでした

C:\Temp> t.exe < test.in 

など

C:\Temp> cat test.in | t.exe 

C:\Temp> t.exe <test.in> test.out 

を走りました。しかし、1,000,000文字がスクロールするのを待つのにかなり時間がかかりました。

+0

私も問題はありません:Vista x64上の80x86用のMicrosoft(R)32-bit C/C++最適化コンパイラバージョン15.00.30729.01。 –

+0

優れた徹底的なテスト!それを確認していただきありがとうございます。 – SPWorley

0

各ループの繰り返し中に短時間スリープ状態にすることができますか?これにより、OSにバッファをフラッシュする機会が与えられます。

私はこれを行うためのコマンドは、C++であるのか分からないが、C#で、それはあなたがこのようにその内容をフラッシュするために、バッファを強制しようとするかもしれ

System.Threading.Sleep(10); 
4

です:

cout << (*j) << std::flush; 

(あなたは私が思うたくない?)そうでなければstd::endlも動作しますが、あまりにも提供し、行の最後特に正しくマイケル・バリへのすべての提案のための

0

win32でstdoutに特殊文字を書き込もうとすると、この問題が発生しました。あなたのテストデータの中のそのような文字は?

1

問題は、おそらくパイプ演算子(|)が "cat"ではないでしょう。 Windowsコマンドインタープリタ[1]にはUnixのような実際のパイプはなく、一時ファイルを使ってシミュレートします。ディスク領域が不足しているか、コマンドインタープリタ内のバッファがあふれている可能性があります。

「bigfile.txt | reverse.exe」と入力しても同じ結果が得られるかどうかを確認してください。

[1]少なくとも古いバージョンには、実際のパイプがありませんでした。私は最新のバージョンを見ていない。 Michael BurrがVista x64で再現できなかったのは興味深いことです。たぶん、MSは問題を解決しました。