2015-10-11 15 views
3

我爲進度條寫了一個標題。它包含以下功能:管道cout干擾cerr

/** 
* @brief advances the progress bar every time an interval of x 
*  function calls has been completed 
* @param current the current iteration 
* @param o the stream to write to 
*/ 
inline void run(step current, sost& o=std::cerr) 
{ 
    if(current%interval == 0 && !(current > max)) 
    { 
     // do away with the cursor 
     #ifdef UNIXLIKE 
     printf("\e[?25l"); 
     #endif 

     // fill line with background symbol 
     for (int i = 0; i < PSD+lbracketSize; ++i) o << " "; 
     for (unsigned i = 0; i < pres; ++i) o << pre; 
     o << rbracket << "\r"; 
     o.flush(); 

     // calculate percentage and make a string of it 
     float prct = ((float)current/max)*100; 
     sstr strprct = helper::to_string((int)prct); 
     // get percantge to length of three 
     if (helper::utf8_size(strprct) < 2) strprct = " "+strprct; 
     if (helper::utf8_size(strprct) < 3) strprct = " "+strprct; 

     // print percentage and bar 
     o << "[" << strprct << "% ] " << lbracket; 
     for (auto i = pbar.begin(); i != pbar.end(); ++i) o << *i; 

     o << "\r"; 
     o.flush(); 

     pbar.push_back(bar); 
    } 
    if(current>=max-1) 
    { 
     cancel(); 
    } 
} 

它工作正常。正如你所看到的,我將進度條發送到stderr。後面的想法是,我可以將我的程序輸出到stdout,而無需捕捉stderr上的進度條。但在實踐中,這並不奏效。雖然進度條沒有按預期得到管道捕捉,但\r命令似乎不起作用,因爲該欄用不斷更新的新行寫入,而不是保持在同一行上,因爲它沒有,當我沒有管道標準輸出。這是爲什麼?對我沒有任何意義。

所以,通常在酒吧看起來是這樣的:

[ 37% ] ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 

當我管標準輸出到一個文件,我得到這一切在我的終端無數行:

 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 
+0

我無法複製此內容。你在使用哪種外殼? –

+0

iTerm2與bash和yakuake bash –

回答

3

請檢查如果stdout被重定向,以下代碼對您無法正常工作:

#include <iostream> 

int main(int argc, char ** argv) 
{ 
    std::cerr << "Hello,\rWorld!\n"; 
    return 0; 
} 

我有一些建議爲您的代碼:

  1. printf("\e[?25l");應改爲o << "\e[?25l"。你不應該混合使用stdio.hiostream,你應該輸出控制序列到stderr。

  2. stderr也可以被重定向。您需要檢查流是否爲終端並檢測終端的功能。該實現是系統特定的。其中一個解決方案可以找到here。另外this link可能會有所幫助。

  3. 您可以通過使用tty命令獲取終端的名稱並寫入它來強制輸出到終端。

+0

該代碼段確實工作正常。 './a.out>文件'寫道「世界!」到終端,並沒有任何文件' –

+0

嘗試創建一個最小的可重現的問題的例子。 –