printf 包装器 [英] Wrapper for printf

查看:26
本文介绍了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.你必须使用 vsprintfvsnprintf:

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:

http://ideone.com/loTRNL

链接到 va_copy 手册页:https://linux.die.net/man/3/va_copy

这篇关于printf 包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆