C - Sprintf 的变量参数?

标签 c variadic-functions

我有一个功能;

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/

相关文章:

c++如何结合std::bind和可变元组?

tcl - 如何在tcl中将变量参数从一个函数传递给另一个函数

ios - 是否可以从 Visual Studio 2013 为 iOS 构建静态(.a)库?

c++ - Makefile - 通配符,如何正确执行?

haskell - 如何创建多变量 Haskell 函数?

c - 用户在运行时动态地进行多个输入

c++ - 将地址转换为长变量结果值?

c - 为什么它要求相同但在代码中只有 1 个 printf()?

c - pthread 退出时如何防止进程退出?

c - 我想编写一个检索网页的函数