printf的包装

我在Arduino下编码,我想开发串行打印格式化function,所以我试图使用未知大小的缓冲区的sprintf 。 基本上,我们可以避免谈论Arduino及其串行输出,并考虑将文本写入缓冲区然后使用printf打印它。 我试过这个:

 #include  #include  void printf0( const char* format, ... ) { va_list args; va_start(args, format); vprintf(format, args); va_end( args ); } void printf1(const char* format,...) { va_list args; va_start(args, format); char buf[vsnprintf(NULL, 0, format, args)]; sprintf(buf, format, args); printf(buf); va_end(args); } int main() { printf0("Hello, %d!\n", 15); printf1("Hello, %d!\n", 15); return 0; } 

printf0函数是我在这里找到的一个准确的例子。 我的尝试是函数printf1 ,它产生不可预测的数字。 上述程序的示例输出是:

 Hello, 15! Hello, 860799736! 

args是一个va_list ,所以你不能用它来调用sprintf 。 你必须使用vsprintfvsnprintf

 sprintf(buf, format, args); 

应该

 vsnprintf(buf, sizeof buf, format, args); 

此外,您应该为字符串的0终止符添加1到buf的大小:

 char buf[vsnprintf(NULL, 0, format, args) + 1]; 

似乎第一次调用vsnprintf改变args ,所以你必须添加

 va_end(args); va_start(args, format); 

两个电话之间: http : //ideone.com/5YI4Or

似乎对vsnprintf的第一次调用改变了args ,但你不应该两次调用va_start 。 你应该使用va_copy ,所以添加

 va_list args2; va_copy(args2, args); 

在初始化args 。 另外不要忘记调用va_end(args2); 太:

http://ideone.com/loTRNL

链接到va_copy手册页: https : va_copy