如何使用varargs进行小型记录器?

时间:2017-02-17 13:05:24

标签: c

我希望像这样使用一个小型记录器:

logger log;
const char* text = "World";
log.write("Hello %s", text);
log.write("Step %d", 1);

这是我的代码,无法正常运行:

class logger
{
public:
    void write(const char* msg, ...)
    {
        FILE* file = fopen("c:/test.txt", "a");
        if(file != NULL)
        {
            va_list args;
            va_start(args, msg);
            fprintf(file, "%s\n", msg, args);
            va_end(args);
            fclose(file);
        }
    }
};

这就是我得到的:

Hello %s
Step %d

之前我从未使用varargs所以我不确定我是否正确使用它。

1 个答案:

答案 0 :(得分:3)

您认为C的行为方式类似于Java或Python或其他语言,可以" splat"接受varargs的函数的数组参数,但C不是那么复杂。当你将args传递给fprintf时,C会将args(一个va_list类型的变量)的值推送到堆栈上。你需要的是将args的内容推入堆栈。

或者,您可以使用接受va_list作为参数的函数。该函数是vprintf(和朋友vsprintf,vfprintf等)。

你还有另一个问题,那就是你打电话给来电者" msg"参数使用"%s"但后来显然希望fprintf以递归方式将结果用作格式字符串并使用args fprintf。那不行。而只是使用调用者的消息作为格式字符串。

        va_list args;
        va_start(args, msg);
        vfprintf(file, msg, args);
        fputc('\n', file);
        va_end(args);