在C++中,是否有可能使用printf(或類似的)寫入某種緩衝區,然後在程序中稍後將緩衝區寫入屏幕或根據結果丟棄它。C++延遲printf直到需要
我想這樣做,因爲我有一個遞歸函數,只希望在整個遞歸過程中看到打印的內容,如果結果是有趣的。
在C++中,是否有可能使用printf(或類似的)寫入某種緩衝區,然後在程序中稍後將緩衝區寫入屏幕或根據結果丟棄它。C++延遲printf直到需要
我想這樣做,因爲我有一個遞歸函數,只希望在整個遞歸過程中看到打印的內容,如果結果是有趣的。
當然可以。爲此,您可以利用vsnprintf
的力量。我建議某種類包裝的std::string
或std::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
調用。
什麼是使用字符串? 或者一個字符串數組。或者一個集合? 收集所有需要的數據並在需要時打印?
這應該是一個評論,而不是一個答案... – SingerOfTheFall
我認爲這些問題意味着一個答案? –
我希望能有一個已經存在的類,它是一個具有printf函數的緩衝區(如用於在屏幕上放置文本的緩衝區),另一個用於在整個屏幕上將整個塊放在屏幕上。 – DanJAB
該類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);
你可以使用sprintf
功能,做同樣的事情printf
成字符緩衝區。但你不應該。這些舊的C風格函數在C++中已經過時,您應該使用流代替。看起來像std::stringstream
符合你的需要。
對於遞歸函數,最好的辦法是推遲得到的結果,沒有打印出來,所以不是這樣的:
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);
基本上,只有在準備就緒後才能打印。如果由於某些原因您不能直接執行此操作,請將結果保存到某種緩衝區變量中,並在函數結束後對其進行訪問。
這對大多數用途都很好,但這是一個幾乎是隨機的遞歸產生許多有效的結果 – DanJAB
沒有。但可以使用spintf將其打印到緩衝區,並且只有在/如果需要時才使用printf打印 – Gir
爲什麼不能使用條件語句? –