printf 包装器 [英] Wrapper for printf
问题描述
我在 Arduino 下编码,我想开发串行打印格式化功能,所以我尝试使用未知大小的缓冲区的 sprintf
.基本上,我们可以避免谈论 Arduino 及其串行输出,而是考虑将文本写入缓冲区,然后使用 printf
打印它.我试过这个:
I am coding under Arduino and I would like to develop serial print formatting function, so I am trying to use sprintf
of unknown sized buffer. Basically, we can avoid talking about Arduino and its serial output and consider writing text to a buffer and then printing it by using printf
. I've tried this one:
#include <stdio.h>
#include <stdarg.h>
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!
", 15);
printf1("Hello, %d!
", 15);
return 0;
}
printf0
函数是我发现的一个准确示例 此处.我的尝试是函数 printf1
,它产生不可预测的数字.上述程序的示例输出是:
printf0
function is an accurate example I found here. My tries is function printf1
, which produces unpredictable number. Example output of the above programme is:
Hello, 15!
Hello, 860799736!
推荐答案
args
是一个 va_list
,所以你不能用它调用 sprintf
.你必须使用 vsprintf
或 vsnprintf
:
args
is a va_list
, so you cannot call sprintf
with it. You have to use vsprintf
or vsnprintf
:
sprintf(buf, format, args);
应该是
vsnprintf(buf, sizeof buf, format, args);
此外,您应该将 buf
的大小加 1,作为字符串的 0 终止符:
Also you should add 1 to the size of buf
for the 0-terminator of the string:
char buf[vsnprintf(NULL, 0, format, args) + 1];
似乎第一次调用vsnprintf
改变了args
,所以你必须添加
It seems that the first call to vsnprintf
changes args
, so you have to add
va_end(args);
va_start(args, format);
两次调用之间:http://ideone.com/5YI4Or罢工>
between the 2 calls: http://ideone.com/5YI4Or
似乎第一次调用 vsnprintf
改变了 args
,但你不应该调用 va_start
两次.你应该使用 va_copy
代替,所以添加
It seems that the first call to vsnprintf
changes args
, but you should not call va_start
twice. You should use va_copy
instead, so add
va_list args2;
va_copy(args2, args);
在初始化args
之后.也不要忘记调用 va_end(args2);
:
after initializing args
. Also do not forget to call va_end(args2);
too:
链接到 va_copy
手册页:https://linux.die.net/man/3/va_copy
这篇关于printf 包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!