如何把va_list可变参数传送到下一级函数中(如传送到printf)
2014-04-08 11:42
399 查看
最近我在一个LCD上想实现打印格式化字符串的功能,实现这样的功能可有两种方式:
一 最直接的就是自己去解析类似于printf功能的一个函数;
二 比较简单的方法是使用已有的sprintf功能,把格式化字符串打印到一个字符缓冲区中,再将这个字符缓冲区打印到LCD上来。
这里选择了第二种方法!
我已经把这个嵌入式程序弄到pc机上来运行了,第一次编写的代码是这样子的:
编译时提示错误:
表示没有格式参数!原来我忘记把格式(%d%x%s)对应的参数(254 0x32 "tfAna")写上去。所以先加上,这些可变参数,就是lcm_appendf的“第二个参数”...
直接写成snprintf(fm_buffer, 128, fmt, ...)显然是不行的!那么我怎么把lcm_appendf中的...转化为snprintf可以接受的参数呢?答案是使用va_list这个可变参数类型。
所以修改后的代码变成这样子:
这时再编译就不再有什么错误提示了,但运行之后的结果是这样子的:
乱码!
网上百度了一圈没有找到答案,然后google了一下国外网站,看到stackoverflow上有人也有同样的问题
http://stackoverflow.com/questions/5977326/call-printf-using-va-list
原来,得使用vprintf啊!对应于我这里就是使用vsnprintf了。(参考这个函数的用法http://en.cppreference.com/w/cpp/io/c/vfprintf)
再修改源码为:
结果就正确了:
一 最直接的就是自己去解析类似于printf功能的一个函数;
二 比较简单的方法是使用已有的sprintf功能,把格式化字符串打印到一个字符缓冲区中,再将这个字符缓冲区打印到LCD上来。
这里选择了第二种方法!
我已经把这个嵌入式程序弄到pc机上来运行了,第一次编写的代码是这样子的:
#include <stdio.h> #include <stdarg.h> void lcm_appendf(const char *fmt, ...) { char fm_buffer[128]; int fm_len = 0; fm_len = snprintf(fm_buffer, 128, fmt); printf("fm_len = %d\r\n", fm_len); printf("%s", fm_buffer); } int main(int argc, char **args) { char c; // printf("Hello, this is Merlin Dec:%d, Hex:0x%x, Str:%s\r\n", 254, 0x32, "tfAna"); lcm_appendf("Hello, this is Merlin Dec:%d, Hex:%x, Str:%s\r\n", 254, 0x32, "tfAna"); scanf("%c", &c); }
编译时提示错误:
$ gcc lcm_appendf.c lcm_appendf.c: In function ‘lcm_appendf’: lcm_appendf.c:8:2: warning: format not a string literal and no format arguments [-Wformat-security] lcm_appendf.c:8:2: warning: format not a string literal and no format arguments [-Wformat-security]
表示没有格式参数!原来我忘记把格式(%d%x%s)对应的参数(254 0x32 "tfAna")写上去。所以先加上,这些可变参数,就是lcm_appendf的“第二个参数”...
直接写成snprintf(fm_buffer, 128, fmt, ...)显然是不行的!那么我怎么把lcm_appendf中的...转化为snprintf可以接受的参数呢?答案是使用va_list这个可变参数类型。
所以修改后的代码变成这样子:
#include <stdio.h> #include <stdarg.h> void lcm_appendf(const char *fmt, ...) { char fm_buffer[128]; int fm_len = 0; va_list ap; va_start(ap, fmt); fm_len = snprintf(fm_buffer, 128, fmt, ap); va_end(ap); printf("fm_len = %d\r\n", fm_len); printf("%s", fm_buffer); } int main(int argc, char **args) { char c; // printf("Hello, this is Merlin Dec:%d, Hex:0x%x, Str:%s\r\n", 254, 0x32, "tfAna"); lcm_appendf("Hello, this is Merlin Dec:%d, Hex:%x, Str:%s\r\n", 254, 0x32, "tfAna"); scanf("%c", &c); }
这时再编译就不再有什么错误提示了,但运行之后的结果是这样子的:
乱码!
网上百度了一圈没有找到答案,然后google了一下国外网站,看到stackoverflow上有人也有同样的问题
http://stackoverflow.com/questions/5977326/call-printf-using-va-list
原来,得使用vprintf啊!对应于我这里就是使用vsnprintf了。(参考这个函数的用法http://en.cppreference.com/w/cpp/io/c/vfprintf)
再修改源码为:
#include <stdio.h> #include <stdarg.h> void lcm_appendf(const char *fmt, ...) { char fm_buffer[128]; int fm_len = 0; va_list ap; va_start(ap, fmt); fm_len = vsnprintf(fm_buffer, 128, fmt, ap); va_end(ap); printf("fm_len = %d\r\n", fm_len); printf("%s", fm_buffer); } int main(int argc, char **args) { char c; // printf("Hello, this is Merlin Dec:%d, Hex:0x%x, Str:%s\r\n", 254, 0x32, "tfAna"); lcm_appendf("Hello, this is Merlin Dec:%d, Hex:%x, Str:%s\r\n", 254, 0x32, "tfAna"); scanf("%c", &c); }
结果就正确了:
相关文章推荐
- 可变参数函数printf的实现(不使用va_list等内置宏定义)
- va_list、va_start、va_end(用于实现函数参数的个数可变的函数,如scanf()/printf()系列函数)
- 如何获取函数的可变参数(va_list, va_start, va_arg, va_end)
- 详解 C语言可变参数 va_list和_vsnprintf及printf实现
- 详解_C语言可变参数_va_list和_vsnprintf及printf实现
- 有关va_list和vsnprintf输出函数的问题(可变参数)
- 关于C中函数的可变参数va_list...(转)
- 详解_C语言可变参数_va_list和_vsnprintf及printf实现
- va_list(可变参数函数的使用)
- 可变参数函数分析(va_list,va_start(),va_end())
- 详解_C语言可变参数_va_list和_vsnprintf及printf实现
- 有关va_list和vsnprintf输出函数的问题(可变参数)
- 【转载】va_list 可变参数 简介 va_copy vprintf
- va_start,va_arg,va_end,va_list应用举例--实现可变参数的函数
- 可变参数列表的函数调用 va_list va_start va_arg va_end
- 函数可变参数深入分析之va_list、va_start、va_arg、va_end
- 详解C语言可变参数 va_list和_vsnprintf及printf实现
- C语言利用va_list、va_start、va_end、va_arg宏定义可变参数的函数
- 使用va_list编写可变参数的函数
- printf函数可变参数是如何实现的?