[英]How to pass variable number of arguments to printf/sprintf
I have a class that holds an "error" function that will format some text. 我有一个类,其中包含一个“错误”函数,该函数将格式化某些文本。 I want to accept a variable number of arguments and then format them using printf. 我想接受可变数量的参数,然后使用printf格式化它们。
Example: 例:
class MyClass
{
public:
void Error(const char* format, ...);
};
The Error method should take in the parameters, call printf/sprintf to format it and then do something with it. Error方法应该接受参数,调用printf / sprintf对其进行格式化,然后对其进行处理。 I don't want to write all the formatting myself so it makes sense to try and figure out how to use the existing formatting. 我不想自己写所有格式,因此尝试弄清楚如何使用现有格式很有意义。
void Error(const char* format, ...)
{
va_list argptr;
va_start(argptr, format);
vfprintf(stderr, format, argptr);
va_end(argptr);
}
If you want to manipulate the string before you display it and really do need it stored in a buffer first, use vsnprintf
instead of vsprintf
. 如果要在显示字符串之前对其进行操作,并且确实确实需要首先将其存储在缓冲区中,请使用vsnprintf
而不是vsprintf
。 vsnprintf
will prevent an accidental buffer overflow error. vsnprintf
将防止意外的缓冲区溢出错误。
have a look at vsnprintf as this will do what ya want http://www.cplusplus.com/reference/clibrary/cstdio/vsprintf/ 看看vsnprintf,因为这会满足您的要求http://www.cplusplus.com/reference/clibrary/cstdio/vsprintf/
you will have to init the va_list arg array first, then call it. 您必须先初始化va_list arg数组,然后再调用它。
Example from that link: /* vsprintf example */ 该链接的示例:/ * 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);
}
Using functions with the ellipses is not very safe. 在椭圆上使用函数不是很安全。 If performance is not critical for log function consider using operator overloading as in boost::format. 如果性能对日志功能不是很关键,请考虑像boost :: format那样使用运算符重载。 You could write something like this: 您可以这样写:
#include <sstream>
#include <boost/format.hpp>
#include <iostream>
using namespace std;
class formatted_log_t {
public:
formatted_log_t(const char* msg ) : fmt(msg) {}
~formatted_log_t() { cout << fmt << endl; }
template <typename T>
formatted_log_t& operator %(T value) {
fmt % value;
return *this;
}
protected:
boost::format fmt;
};
formatted_log_t log(const char* msg) { return formatted_log_t( msg ); }
// use
int main ()
{
log("hello %s in %d-th time") % "world" % 10000000;
return 0;
}
The following sample demonstrates possible errors with ellipses: 下面的示例演示了椭圆的可能错误:
int x = SOME_VALUE;
double y = SOME_MORE_VALUE;
printf( "some var = %f, other one %f", y, x ); // no errors at compile time, but error at runtime. compiler do not know types you wanted
log( "some var = %f, other one %f" ) % y % x; // no errors. %f only for compatibility. you could write %1% instead.
I should have read more on existing questions in stack overflow. 我应该阅读有关堆栈溢出中现有问题的更多信息。
C++ Passing Variable Number of Arguments is a similar question. C ++传递可变数量的参数是一个类似的问题。 Mike F has the following explanation: Mike F有以下解释:
There's no way of calling (eg) printf without knowing how many arguments you're passing to it, unless you want to get into naughty and non-portable tricks. 在不知道要传递给它多少参数的情况下,无法调用(例如)printf,除非您想陷入顽皮和不可移植的窍门。
The generally used solution is to always provide an alternate form of vararg functions, so printf has vprintf which takes a va_list in place of the .... The ... versions are just wrappers around the va_list versions. 通常使用的解决方案是始终提供另一种形式的vararg函数,因此printf具有vprintf,它使用va_list代替...。...版本只是va_list版本的包装。
This is exactly what I was looking for. 这正是我想要的。 I performed a test implementation like this: 我执行了这样的测试实施:
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);
}
You are looking for variadic functions . 您正在寻找可变参数函数 。 printf() and sprintf() are variadic functions - they can accept a variable number of arguments. printf()和sprintf()是可变参数函数-它们可以接受可变数量的参数。
This entails basically these steps: 这基本上包括以下步骤:
The first parameter must give some indication of the number of parameters that follow. 第一个参数必须说明后面的参数数量。 So in printf(), the "format" parameter gives this indication - if you have 5 format specifiers, then it will look for 5 more arguments (for a total of 6 arguments.) The first argument could be an integer (eg "myfunction(3, a, b, c)" where "3" signifies "3 arguments) 因此,在printf()中,“ format”参数给出了这一指示-如果您有5个格式说明符,则它将查找另外5个参数(总共6个参数。)第一个参数可以是整数(例如“ myfunction” (3,a,b,c)”,其中“ 3”表示“ 3个自变量”
Then loop through and retrieve each successive argument, using the va_start() etc. functions. 然后使用va_start()等函数循环遍历并检索每个连续的参数。
There are plenty of tutorials on how to do this - good luck! 有很多关于如何执行此操作的教程-祝您好运!
Simple example below. 下面的简单示例。 Note you should pass in a larger buffer, and test to see if the buffer was large enough or not 请注意,您应该传递更大的缓冲区,并测试缓冲区是否足够大
void Log(LPCWSTR pFormat, ...)
{
va_list pArg;
va_start(pArg, pFormat);
char buf[1000];
int len = _vsntprintf(buf, 1000, pFormat, pArg);
va_end(pArg);
//do something with buf
}
看一下示例http://www.cplusplus.com/reference/clibrary/cstdarg/va_arg/ ,它们将参数数量传递给方法,但是您可以忽略该参数并适当地修改代码(请参见示例)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.