为了输出格式化的调试输出,我为编写了包装器vsfprint
。现在,我想为输出缓冲区分配足够的内存,而不是仅仅声称随机的高缓冲区大小(这是一个小型嵌入式平台(ESP8266))。为此,我遍历变量参数,直到找到NULL。
只要我不忘记(char *)NULL
为每个调用添加参数,就可以正常工作。因此,我认为,让我们创建另一个包装器,一个仅中继所有参数并添加(char *) NULL
参数的函数:
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // malloc
void write_log(const char *format, ...) {
char* buffdyn;
va_list args;
// CALC. MEMORY
size_t len;
char *p;
if(format == NULL)
return;
len = strlen(format);
va_start(args, format);
while((p = va_arg(args, char *)) != NULL)
len += strlen(p);
va_end(args);
// END CALC. MEMORY
// ALLOCATE MEMORY
buffdyn = malloc(len + 1); /* +1 for trailing \0 */
if(buffdyn == NULL) {
printf("Not enough memory to process message.");
return;
}
va_start(args, format);
//vsnprintf = Write formatted data from variable argument list to sized buffer
vsnprintf(buffdyn, len, format, args);
va_end(args);
printf("%s\r\n",buffdyn);
free(buffdyn);
}
void write_log_wrapper(const char *format, ...) {
va_list arg;
va_start(arg, format);
write_log(format,arg,(char *)NULL);
va_end(arg);
}
int main()
{
const char* sDeviceName = "TEST123";
const char* sFiller1 = "12345678";
write_log_wrapper("Welcome to %s%s", sDeviceName,sFiller1);
write_log("Welcome to %s%s", sDeviceName,sFiller1, (char *)NULL);
return 0;
}
write_log()
直接调用该函数可以正常工作(如果您不忘记NULL参数)。调用该write_log_wrapper()
函数将仅显示第一个参数,然后在输出中添加“(nu)(垃圾?)”。
我究竟做错了什么?这是一种很好的方式来实现我最初打算做的事情吗?
谢谢。
为了确定容纳输出字符串所需的缓冲区大小,您需要完全解析整个格式字符串并实际扩展arguments。
您可以自己进行操作,复制和处理所有内容,printf()
并希望不会出错,或者可以使用vsnprintf()
-首先确定大小,然后将输入实际扩展为一个输出字符串。
#define FIXED_SIZE 64
void write_log(const char *format, ...)
{
// set up a fixed-size buffer and a pointer to it
char fixedSizeBuffer[ FIXED_SIZE ];
char *outputBuffer = fixedSizeBuffer;
// no dynamic buffer yet
char *dynamicBuffer = NULL;
// get the variable args
va_list args1;
va_start( args1, format );
// need to copy the args even though we won't know if we
// need them until after we use the first set
va_list args2;
va_copy( args2, args1 );
// have to call vsnprintf at least once - might as well use a small
// fixed-size buffer just in case the final string fits in it
int len = vsnprintf( fixedSizeBuffer, sizeof( fixedSizeBuffer ), format, args1 );
va_end( args1 );
// it didn't fit - get a dynamic buffer, expand the string, and
// point the outputBuffer pointer at the dynamic buffer so later
// processing uses the right string
if ( len > sizeof( fixedSizeBuffer ) )
{
dynamicBuffer = malloc( len + 1 );
vsnprintf( dynamicBuffer, len + 1, format, args2 );
outputBuffer = dynamicBuffer;
}
va_end( args2 );
// do something with outputBuffer
free( dynamicBuffer );
return;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句