c++ - vfprintf 无法正常工作

标签 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 到文件。

怎么了?

最佳答案

问题是您正在使用 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_copyva_start 都需要相应调用 va_end

关于c++ - vfprintf 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45100604/

相关文章:

c++ - C++中的鼠标点击位置

c++ - C++ 中的编译时常量

c++ - 我的蹦床弹不起来(绕行,C++,GCC)

pdf - JavaFX - 以编程方式设置目标路径以直接将节点打印到 pdf 文件

android - PrintAttributes 不工作。无法创建自定义页面大小

c++ - OpenACC 与 C++ : FATAL ERROR: variable is partially present on the device

c - 解释 gcov 输出以识别基本 block

gcc - 在编译期间将 "dirty"C 代码与干净代码隔离开来的最佳方法是什么?

gcc - make -j distcc 是否可以扩展超过 5 倍?

java - 数组项目似乎只打印出null