2009-05-22 135 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中對於較大的文件會因「錯誤寫入標準輸出」消息而死亡。它總是死於同一個角色。 像「cat bigfile.txt | reverse.exe」這樣的shell命令就是重現問題所需的全部。 MSFT和英特爾編譯器的行爲都相似。

我意識到stdout上可能有一個緩衝區,但不應該在填充時自動刷新?

+1

我想你需要提供關於你正在運行的編譯器版本,操作系統和內存的更多細節。至少有幾個人沒有看到這個問題。 – 2009-05-23 00:15:39

+0

另外,請嘗試使用類似「reverse.exe 2009-05-23 00:21:04

回答

0

感謝所有的建議,特別是邁克爾伯爾誰正確的或者說,cat命令,而不是rev​​erse.exe,可能會失敗!這正是它是.. reverse.exe < bigfile.txt工作正常,但貓bigfile.txt | reverse.exe失敗,並顯示「寫入stdout錯誤」。 現在爲什麼CAT會失敗也是一個謎,但至少現在不是代碼相關的東西。

1

沒有這樣的問題在這裏:

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

編輯:更多信息

我通過編譯您發佈的程序測試此。我創建了一個由組成的重複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 

有沒有問題。它需要很長時間才能等待100萬個字符滾動。

+0

我也沒有問題:Microsoft(R)32位C/C++優化編譯器版本15.00.30729.01在Vista x64上爲80x86。 – 2009-05-23 00:14:32

0

在每次循環迭代期間,或者可能每100次迭代,您是否可以在短時間內睡眠?這將使操作系統有機會刷新緩衝區。

我不知道這樣做的命令是在C++,但在C#這是

System.Threading.Sleep(10); 
4

您可以嘗試迫使緩衝刷新其內容是這樣的:

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

否則std::endl作品也,但也提供和行結束(你不想我想?)

0

如果您嘗試在win32上編寫特殊字符到標準輸出,則發生此問題之前會發生此問題。測試數據中的任何此類字符?

1

問題可能是管道運算符(|)不是「貓」。 Windows命令解釋器[1]沒有真正的管道(如Unix)並使用臨時文件來模擬它們。您可能會耗盡磁盤空間或溢出命令解釋器中的某個緩衝區。

你可以嘗試「輸入bigfile.txt | reverse.exe」,看看你是否得到相同的結果。

[1]至少舊版本沒有真正的管道。我沒有看過最新的版本。有趣的是,邁克爾伯爾無法在Vista x64上重現它。也許MS已經解決了這個問題。