包装包装 [英] Wrapper for printf

查看:75
本文介绍了包装包装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在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!\n", 15);
    printf1("Hello, %d!\n", 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!

推荐答案

argsva_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);

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

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);:

http://ideone.com/loTRNL

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

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

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