gpt4 book ai didi

C可变包装器

转载 作者:太空狗 更新时间:2023-10-29 15:28:37 26 4
gpt4 key购买 nike

为了输出格式化的调试输出,我为 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”(垃圾?)。

我做错了什么?这是实现我最初的目标的好方法吗?

谢谢。

最佳答案

要确定需要多大的缓冲区来保存输出字符串,您需要完全解析整个格式字符串并实际扩展参数

您可以自己做,复制 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;
}

关于C可变包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37947200/

26 4 0
文章推荐: C - charArray 总是与 &charArray 相同吗?
文章推荐: javascript - 将
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com