printf的包装

时间:2017-02-09 08:39:22

标签: c arduino

我在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!

1 个答案:

答案 0 :(得分:4)

argsva_list,因此您无法使用sprintf来致电vsprintf。您必须使用vsnprintfsprintf(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
两次通话之间

http://ideone.com/5YI4Or

似乎第一次调用args会更改va_start,但您不应该拨打va_copy两次。您应该使用va_list args2; va_copy(args2, args); ,所以添加

args
初始化va_end(args2);

。另外,别忘了拨打va_copy

http://ideone.com/loTRNL

链接到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