背景
最近在做嵌入式开发,定义移植接口时需要定义一个打印接口My_Printf(功能类似printf)。原来是通过宏定义实现。
#define My_Printf printf
这种实现方式可以满足要求,不过使用时引入了对stdio.h头文件的包含,无形中增加头文件依赖。
方案
解决头文件依赖,一种实现方式将My_Printf定义为函数,My_Printf需要处理可以变参数,故函数定义如下:
int My_Printf(const char* format, ...);
实现
在C语言中实现可变参数需要用到stdarg库和vprintf系列函数。函数实现如下:
#include <stdarg.h>
#include <stdio.h>
int My_Printf(const char* format, ...)
{
va_list list;
int len;
va_start(list, format);
len = vprintf(format, list);
va_end(list);
return len;
}
这里使用vprintf将输出打印到stdout。如果嵌入式系统中需要通过其它方式输出可以使用vsnprintf将要输入输出字符串中或者通过vfprintf输出到文件中。下面代码将演示这两种方式。
输入到文本
使用vsnprintf函数输入到文本中
#include <stdarg.h>
#include <stdio.h>
#define TEXT_MAX_SIZE 1024
int My_Printf(const char* format, ...)
{
static char text[TEXT_MAX_SIZE + 1];// +1 for '\0'
va_list list;
int size;
va_start(list, format);
size = vsnprintf(text, TEXT_MAX_SIZE, format, list);
//这里可以利用嵌入式系统中输出函数将text字符串输出到指定终端
va_end(list);
return size;
}
输入到文件
使用vfprintf函数输入到文本中
#include <stdarg.h>
#include <stdio.h>
#define FILE_NAME "mylog.txt"
int My_Printf(const char* format, ...)
{
FILE* file = fopen(FILE_NAME, "a");
va_list list;
int size = 0;
if(file)
return size;
va_start(list, format);
size = vfprintf(file, format, list);
fclose(file);
va_end(list);
return size;
}