2013-04-23 26 views
0

我想在我的程序中加載一個216,555字的巨大文本文件並將它們作爲字符串放入一組中。這可以正常工作,但正如預期的那樣,它將在循環播放文件時掛起幾秒鐘。但是我的循環有一些奇怪的現象,而且行爲不正常。請花時間閱讀,我相信這是有道理的,但我不知道要搜索什麼。C++意外的掛起時間

的代碼,這是由工作方式,是這樣的:

ifstream dictionary; 
dictionary.open("Dictionary.txt"); 

if(dictionary.fail()) 
{ 
    cout<<"Could not find Dictionary.txt. Exiting."<<endl; 
    exit(0); 
} 
int i = 0; 
int progress = 216555/50; 
cout<<"Loading dictionary..."<<endl; 
cout<<"<             >"<<endl; 
cout<<"<"; 
for(string line; getline(dictionary, line);) 
{ 
    usleep(1); //Explanation below (not the hangtime) 
    i++; 
    if(i%progress == 0) 
     cout<<"="; 
    words.insert(line); 
} 

的for循環從文件每一個字符串,然後將它們插入地圖。 這是一個控制檯應用程序,我希望用戶看到進度。這並沒有太大的延遲,但我仍然想要這樣做。如果你不明白代碼,我會盡力解釋。

程序啓動時,首先打印出「正在載入字典...」,然後打印出一個「<」和一個「>」分隔50個空格。然後在下一行:「<」後面跟着一個「=」,每循環433個單詞(216555/50)。這樣做的目的是讓用戶可以看到進展情況。通過循環所需輸出一半會是這樣的:

Loading dictionary... 
<             > 
<=========================       

我的問題是: 正確的輸出顯示,但不能在預期的時間。它打印出完整的進度條,但是隻有在掛起並完成循環後才能進行。這怎麼可能?顯示正確的數字'=',但它們都會同時彈出,在它掛起幾微秒之後。我添加了usleep(1),使掛機時間稍長一些,但同樣的事情發生了。 if語句清楚地工作,或者'='根本不會顯示,但感覺就像我的程序在整個循環之後堆疊cout-calls。

最奇怪的是,for循環開始前的最後cout<<"<";也與其餘行同時顯示;循環結束後。爲什麼和如何?

回答

1

程序 「堆疊COUT通話」。它被稱爲輸出緩衝,並且每個主要的操作系統都會這樣做。

在交互模式下(因爲您的程序是打算使用的),輸出按行緩衝;也就是說,當看到換行符時它將被強制送到終端。您也可以使用塊緩衝(強制輸出之間固定數量的字節;當輸出管道時使用)和無緩衝。

C++提供std::flush流修飾符來強制任何點的輸出。它可以像這樣使用:

cout << "=" << std::flush; 

這會讓您的程序稍稍變慢;緩衝的重點在於效率。因爲你只會做51次左右,但放緩應該可以忽略不計。

+0

謝謝!你是否也碰巧知道是否有可能在已經打印出來的東西之前打印出某些東西?我希望輸出爲'<=== - >',其中用戶可以在運行時看到進度條的結尾,但這是不可能的,除非每次打印完整行。您是否明白我的意思,也許知道我應該尋找什麼? – Sti 2013-04-23 04:27:13

+0

順便說一句,我找到了。我只是把'\ r'放在字符串的後面,它會覆蓋(不在Xcode中) – Sti 2013-04-23 05:20:35

+0

是的,回車符('\ r')將光標重置到行的開頭,允許您覆蓋行。 (請記住,它不會自動覆蓋該行。) – michaelb958 2013-04-23 11:57:27

3

您從不刷新流,所以輸出只進入緩衝區。

變化cout<<"=";cout<<"="<<std::flush;

3

您需要刷新輸出流。

cout << "=" << std::flush;