我在Arduino下编码,我想开发串行打印格式化功能,所以我试图使用未知大小缓冲区的sprintf
。基本上,我们可以避免谈论Arduino及其串行输出,并考虑将文本写入缓冲区,然后使用printf
进行打印。我试过这个:
#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!\n", 15);
printf1("Hello, %d!\n", 15);
return 0;
}
printf0
函数是我找到的here的准确示例。我的尝试是函数printf1
,它产生不可预测的数字。上述程序的示例输出是:
Hello, 15!
Hello, 860799736!
答案 0 :(得分:4)
args
是va_list
,因此您无法使用sprintf
来致电vsprintf
。您必须使用vsnprintf
或sprintf(buf, format, args);
:
vsnprintf(buf, sizeof buf, format, args);
应该是
buf
此外,对于字符串的0结尾符号,您应该为char buf[vsnprintf(NULL, 0, format, args) + 1];
的大小添加1:
vsnprintf
似乎第一次调用 args
会更改va_end(args);
va_start(args, format);
,因此您必须添加
vsnprintf
两次通话之间似乎第一次调用args
会更改va_start
,但您不应该拨打va_copy
两次。您应该使用va_list args2;
va_copy(args2, args);
,所以添加
args
初始化va_end(args2);
后。另外,别忘了拨打va_copy
:
链接到SELECT CAST(getdate() AS DATE)---'2/9/2017 12:00:00 AM'
SELECT CAST('2017/01/15' AS DATE)----'1/15/2017 12:00:00 AM'
SELECT IIF(CAST(getdate() AS DATE) > CAST('2017/01/15' AS DATE),1,0); --good, you must use iif (or case when ) for predicates
手册页:https://linux.die.net/man/3/va_copy