2012-09-03 77 views
1

在C++中,是否有可能使用printf(或類似的)寫入某種緩衝區,然後在程序中稍後將緩衝區寫入屏幕或根據結果丟棄它。C++延遲printf直到需要

我想這樣做,因爲我有一個遞歸函數,只希望在整個遞歸過程中看到打印的內容,如果結果是有趣的。

+0

沒有。但可以使用spintf將其打印到緩衝區,並且只有在/如果需要時才使用printf打印 – Gir

+0

爲什麼不能使用條件語句? –

回答

1

當然可以。爲此,您可以利用vsnprintf的力量。我建議某種類包裝的std::stringstd::vector<char>(在C++ 11基本相同):

#include <cstdargs> 
#include <cstdio> 
#include <string> 

class Formatter 
{ 
    std::string buf; 
public: 
    void add(char const * fmt, ...) 
    { 
     std::va_list ap, aq; 
     va_start(ap, fmt); 
     va_copy(aq, ap); 

     int ret1 = std::vsnprintf(NULL, 0, fmt, ap); 
     // check ret1 != -1 

     std::size_t cur = buf.size(); 
     buf.resize(cur + ret1 + 1); 

     int ret2 = std::vsnprintf(&buf[cur], ret1 + 1, fmt, aq); 
     // check ret2 != -1 
     buf.resize(cur + ret1); 

     va_end(aq); 
     va_end(ap); 
    } 

    std::string const & str() const { return buf; } 
}; 

現在,你可以說:

Formatter f; 
f.add("Hello, %s", "world"); 
f.add("%i%i%i", 1, 2, 3); 
std::cout << f.str() << std::endl; 

如果你很在意性能,您可以嘗試爲打印操作預先分配一些空間,並保留一個單獨的「結束」位置,希望您不必多次運行vnsprintf調用。

+0

我喜歡這種方法的外觀,但找不到合適的包括使用 – DanJAB

+0

您需要'','和' '。我會編輯它。 –

+0

明白了,我的錯誤,我已經有了這些,但沒有注意到錯誤,說無效的編譯器指令#includ(我忘了E),這很好,我還添加了一個明確的功能,只是做了buf =「」; – DanJAB

0

什麼是使用字符串? 或者一個字符串數組。或者一個集合? 收集所有需要的數據並在需要時打印?

+2

這應該是一個評論,而不是一個答案... – SingerOfTheFall

+0

我認爲這些問題意味着一個答案? –

+0

我希望能有一個已經存在的類,它是一個具有printf函數的緩衝區(如用於在屏幕上放置文本的緩衝區),另一個用於在整個屏幕上將整個塊放在屏幕上。 – DanJAB

4

該類std::ostringstream是你在找什麼。

在C++中,格式化IO完成(最好)通過<iostream>庫。這是着名的cout << variable << endl

cout直接輸出到標準輸出。如果你想,而不是緩衝,您可以將輸出重定向到一個std::ostringstream實例以後可以重定向到標準輸出:

#include <iostream> 

[...] 


ostringstream buf; 
buf << myVar1 << "MyStr" << endl; 

[...] // some time later 

cout << buf.str(); 

如果你喜歡做的事情的printf方式,你可以使用sprintf(雖然我不會推薦它)。這有點複雜,因爲您需要事先知道緩衝區的大小。

char myBuf[10000]; // up to you do to the proper bound checking 
sprintf(myBuf, "format %d", myvar); 

[...] // you may want to use strcat and such for more complex operations 

printf(myBuf); 
0

你可以使用sprintf功能,做同樣的事情printf成字符緩衝區。但你不應該。這些舊的C風格函數在C++中已經過時,您應該使用流代替。看起來像std::stringstream符合你的需要。

0

對於遞歸函數,最好的辦法是推遲得到的結果,沒有打印出來,所以不是這樣的:

int fact(int n) 
{ 
    printf("%d", n); 
    if(n!=1) 
     return n * fact(n - 1); 
    else return 1; 
}; 
<....> 
fact(5); 

您可以使用此:

int fact(int n) 
{ 
    if(n!=1) 
     return n * fact(n - 1); 
    else return 1; 
}; 
<....> 
int result = fact(5); 
printf("%d", result); 

基本上,只有在準備就緒後才能打印。如果由於某些原因您不能直接執行此操作,請將結果保存到某種緩衝區變量中,並在函數結束後對其進行訪問。

+0

這對大多數用途都很好,但這是一個幾乎是隨機的遞歸產生許多有效的結果 – DanJAB