vfprintf无法正常工作

时间:2017-07-14 10:22:43

标签: 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);

    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打印到文件中。

怎么了?

1 个答案:

答案 0 :(得分:1)

问题在于您使用了va_list argptr 2次。进入vprintf后进入vfprintf来电。 va_list如何使用堆栈实现定义,请参阅here。例如va_list类型在 Linux x86_64 中实现,如上所述here on SO

  

va_list类型

     

va_list类型是一个数组,其中包含一个结构的单个元素,其中包含实现va_arg宏的必要信息。 va_list类型的定义见图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_copy,请在va_start后使用va_start或使用va_copy 2次。但请记住,每次拨打va_copyva_start都需要拨打va_end