C++ vfprintf不';我不能正常工作
我有一门课:C++ vfprintf不';我不能正常工作,c++,gcc,printing,printf,C++,Gcc,Printing,Printf,我有一门课: 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);
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)时代码>它将测试0@WAíõ0000000
打印到文件中
出什么问题了?问题是您使用了va_列表
argptr
两次。一次在vprintf
中,第二次在vfprintf
调用中。va_列表
如何与堆栈一起工作是实现定义的,请参阅。例如,va_列表
类型在Linux x86_64中实现,如下所述:
va_列表类型
va_列表类型是一个数组,包含一个结构的单个元素,其中包含实现va_arg宏所需的信息。va_列表类型的定义如图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_列表
传递到第一个vprintf
调用中,并且函数返回va_列表
将不再像调用之前那样。第二次调用vfprintf
将得到一个“错误/消耗的va_列表”
”
解决方案:
在va_start
之后使用va_copy
,或者如果编译器不支持va_copy
,则使用va_start
两次。但是请记住,每次调用va_copy
或va_start
都需要相应的调用va_end
,DEBUG_D
宏(我想?)做什么?请检查函数调用的返回值并告诉它们,例如vfprintf()
。此外,您还可以检查errno
变量。哪些值属于哪个函数?可以,但对于errno
您必须在每次调用之前将其设置为errno=0
。然后您的值就可以了。22是在不计算空字节的情况下写入错误字符串的字节数。如果不使用double
而是使用int
,会发生什么?