我有一个功能;
void foo(const char* format, ...)
{
char buffer[1080];
// Supposed way to handle C Variable Arguments?
va_list argptr;
va_start(argptr, format);
sprintf(buffer, format, argptr);
va_end(argptr);
printf_s("%s.\n", buffer);
}
int main()
{
int val = 53;
foo("%d", val);
}
每次我运行这个程序时,我都会得到大量的数字,这些数字在每次运行期间都会发生变化。 12253360
, 5306452
等等,我不明白为什么。
这是我的 sprintf
调用的问题还是我执行 va_list argptr;
的方式?我的 buffer
太大了吗?
谢谢。
最佳答案
您显然尝试使用的技术表明您需要 vsprintf
(或者,更好的是 vsnprintf
)
va_list argptr;
va_start(argptr, format);
vsnprintf(buffer, sizeof buffer, format, argptr);
va_end(argptr);
这就是来自 v...
组的函数存在于标准库中的原因。
以您的方式调用 sprintf
完全没有意义 - 它不能与外部提供的 va_list
一起使用。
如果你想实现一个可变大小的缓冲区,你可以按如下方式实现
void foo(const char* format, ...)
{
static char *buffer;
static size_t buffer_size;
va_list argptr;
va_start(argptr, format);
int length = vsnprintf(buffer, buffer_size, format, argptr);
va_end(argptr);
if (length + 1 > buffer_size)
{
buffer_size = length + 1;
buffer = realloc(buffer, buffer_size);
/* Yes, `realloc` should be done differently to properly handle
possible failures. But that's beside the point in this context */
va_start(argptr, format);
vsnprintf(buffer, buffer_size, format, argptr);
va_end(argptr);
}
printf("%s.\n", buffer);
}
当然,您可以将内存管理策略更改为不同的东西,比如在第一次调用中使用 512
字节的固定本地缓冲区,然后在第二次调用中使用临时动态分配的缓冲区仅在 512
证明不足时才调用。等等……
关于C - Sprintf 的变量参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43129133/