如何将可变数量的参数传递给printf/sprintf

use*_*722 76 c c++ printf variadic-functions

我有一个类,它包含一个"错误"函数,可以格式化一些文本.我想接受可变数量的参数,然后使用printf格式化它们.

例:

class MyClass
{
public:
    void Error(const char* format, ...);
};
Run Code Online (Sandbox Code Playgroud)

Error方法应该接受参数,调用printf/sprintf来格式化它然后用它做一些事情.我不想自己编写所有格式,因此尝试找出如何使用现有格式是有意义的.

Joh*_*ica 143

void Error(const char* format, ...)
{
    va_list argptr;
    va_start(argptr, format);
    vfprintf(stderr, format, argptr);
    va_end(argptr);
}
Run Code Online (Sandbox Code Playgroud)

这段代码不太好.它使用固定大小的字符缓冲区,如果字符串病态长,则可能导致缓冲区溢出错误.任意大vsnprintf尺寸都应该在你脑海中掀起一面旗帜.此外,vsprintf如果vsnprintf最终包含格式代码,则调用可能会遇到问题.更好的是vsnprintf.但更好的是仍然会使用vsprintfvsnprintf:

void Error(const char* format, ...)
{
    va_list argptr;
    va_start(argptr, format);
    vfprintf(stderr, format, argptr);
    va_end(argptr);
}
Run Code Online (Sandbox Code Playgroud)

如果你想在显示之前操纵字符串并且确实需要先将它存储在缓冲区中,请使用vsnprintf而不是代替vsprintf.vsnprintf将防止意外的缓冲区溢出错误.


Lod*_*dle 31

看看vsnprintf,因为这会做你想要的事情http://www.cplusplus.com/reference/clibrary/cstdio/vsprintf/

你必须先启动va_list arg数组,然后调用它.

该链接的示例:/*vsprintf示例*/

#include <stdio.h>
#include <stdarg.h>

void Error (char * format, ...)
{
  char buffer[256];
  va_list args;
  va_start (args, format);
  vsnprintf (buffer, 255, format, args);


  //do something with the error

  va_end (args);
}
Run Code Online (Sandbox Code Playgroud)

  • [vsnprintf](http://linux.die.net/man/3/vsnprintf)的第二个参数应该是缓冲区长度,包括终止空字节('\ 0').所以你可以在函数调用中使用256而不是255. (6认同)

use*_*722 5

我应该阅读有关堆栈溢出中现有问题的更多信息。

C++ 传递可变数量的参数是一个类似的问题。Mike F有如下解释:

如果不知道要传递给它多少个参数,就无法调用(例如) printf ,除非您想使用顽皮且不可移植的技巧。

通常使用的解决方案是始终提供可变参数函数的替代形式,因此 printf 有 vprintf,它使用 va_list 代替 .... ... 版本只是 va_list 版本的包装器。

这正是我一直在寻找的。我执行了这样的测试实现:

void Error(const char* format, ...)
{
    char dest[1024 * 16];
    va_list argptr;
    va_start(argptr, format);
    vsprintf(dest, format, argptr);
    va_end(argptr);
    printf(dest);
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 printf(dest) ,直到 dest 恰好包含“%s”或“%d”,然后 *BOOM*。请使用 printf("%s", dest)。 (4认同)