在c ++中,是否可以使用printf(或类似文件)写入某种缓冲区,然后在程序中将缓冲区写入屏幕或根据结果丢弃它。
我想这样做是因为我有一个递归函数,并且只希望在结果感兴趣时看到整个递归中打印的东西。
答案 0 :(得分:4)
班级std::ostringstream
正是您要找的。 p>
在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);
答案 1 :(得分:1)
当然可以。您可以为此目的利用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
调用不止一次。
答案 2 :(得分:0)
使用字符串是什么意思? 或者一个字符串数组。还是收藏品? 收集您需要的所有数据并在需要时打印?
答案 3 :(得分:0)
您可以使用与sprintf
完全相同的printf
函数进入char缓冲区。但你不应该。这些旧的C风格函数在C ++中已经过时,你应该使用流来代替。看起来std::stringstream
符合您的需求。
答案 4 :(得分: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);
基本上,只有在准备就绪时才打印出来。如果由于某些原因你不能直接进行,将结果保存到某种缓冲变量中,并在函数结束后访问它。