Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ vfprintf不';我不能正常工作_C++_Gcc_Printing_Printf - Fatal编程技术网

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
,会发生什么?