我有一个类:
FILE *logFile = fopen("out.log", "w");
class Log {
public:
static void d(const char *message, ...) __attribute__((format (printf, 1, 2)));
}
在源文件中:
void Log::d(const char *message, ...) {
va_list argptr;
va_start(argptr, message);
vprintf(message, argptr);
printf("\n");
fflush(stdout);
if (logFile) {
vfprintf(logFile, message, argptr);
fprintf(logFile, "\n");
fflush(logFile);
}
va_end(argptr);
}
但是当我调用 Log::d("test %d %s %f", 10, "str", 0.1);
时,它会打印 test 0 @WAíõ 0 ,000000
到文件。
怎么了?
最佳答案
问题是您正在使用 va_list
argptr
2 次。一次在 vprintf
中,然后在 vfprintf
调用中。 va_list
如何与堆栈一起工作是实现定义的,参见 here .例如,va_list
类型在 Linux x86_64 中实现,如 here on SO 所述:
The va_list Type
The va_list type is an array containing a single element of one structure containing the necessary information to implement the va_arg macro. The C definition of va_list type is given in figure 3.34
// Figure 3.34 typedef struct { unsigned int gp_offset; unsigned int fp_offset; void *overflow_arg_area; void *reg_save_area; } va_list[1];
如果您将 va_list
传递给第一个 vprintf
调用并且该函数返回 va_list
将不再像调用之前那样。第二次调用 vfprintf
将得到一个“错误/消耗的 va_list
”。
解决方案:
在va_start
之后使用va_copy
,或者如果您的编译器不支持va_copy
,则使用va_start
2 次。但请记住,每次调用 va_copy
或 va_start
都需要相应调用 va_end
。
关于c++ - vfprintf 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45100604/