如果缓冲区大小小于实际需要的大小,如何知道 vsnprintf 使用了多少个参数?

问题描述 投票:0回答:1

我正在尝试将消息分成 32 字节的块,我正在使用 vsnprintf 来打印消息。但参数并没有增加,即即使在调用 vsnprintf 之后,参数也显示第一个参数。

#define NOR_LOG_MSG_LENGTH      32
void NOR_LOG_MSG(const char* msg, ...)
{
    va_list args;
    va_start(args, msg);
    uint8_t tempMsgBuf[NOR_LOG_MSG_LENGTH] = { 0 };
    int m = vsnprintf((char*)tempMsgBuf, NOR_LOG_MSG_LENGTH, msg, args);
        //I want to use rest of the args in next vsnprintf
    va_end(args);
}

所以,这里真正的问题是,vsnprintf 在使用它后是否会增加参数?我应该如何知道已使用了多少个参数以及还剩下多少个参数,以便我可以调用 va_arg 来增加参数?

c printf
1个回答
0
投票

你想做的事情不会成功。没有办法知道你已经完成了格式字符串多远,或者即使特定的格式说明符能够打印所有必要的字符。

您需要做的是首先调用

snprintf
,第一个参数为 NULL,第二个参数为 0。这将返回存储结果字符串所需的字节数,而无需实际写入任何内容。然后动态分配必要的空间并再次调用它,确保使用单独的
va_start
va_end
集。

void NOR_LOG_MSG(const char* msg, ...)
{
    va_list args;
    va_start(args, msg);
    int m = vsnprintf(NULL, 0, msg, args);
    va_end(args);

    uint8_t *buff = malloc(m + 1);
    if (!buff) return;
    va_start(args, msg);
    vsnprintf(buff, m + 1, msg, args);
    va_end(args);

    // use buff
    free(buf);
}
© www.soinside.com 2019 - 2024. All rights reserved.