【问题标题】:Pass varargs to printf [duplicate]将可变参数传递给 printf [重复]
【发布时间】:2014-02-27 17:32:56
【问题描述】:

我想要一个辅助函数log,它本质上执行以下操作:

log(file, "array has %d elements\n", 10);
// writes "2014-02-03 16:33:00 - array has 10 elements" to &file

time 部分已关闭,文件写入部分已关闭。然而,问题在于log 的方法签名本身——我应该放什么? This 表示 printf 声明以 ... 关键字结尾,但是如何在我的函数中使用它?

void log(FILE *f, const char * format, ...) // how would I pass ... to fprintf?

让我编辑这里包含更多信息。

我有一个const char * now (),它返回一个格式为“2014-02-03 16:33:00”的字符串。我想像这样传递另一个格式字符串。这两个语句应该是等价的:

log(file, "array has %d elements\n", 10);
fprintf(file, "%s - array has %d elements\n", now(), 10);

我知道vfprintf 允许我传递va_list,但是我怎样才能将now() 作为第一个参数,所有其他参数之前?

【问题讨论】:

    标签: c function variadic-functions printf


    【解决方案1】:

    使用vprintf,声明为:

    int vprintf(const char *format, va_list ap);
    

    在您的log 函数中,调用va_start 以获取va_list 值,然后将该值传递给vprintf

    由于您的log 函数采用FILE* 参数,您可能希望使用vfprintf 而不是vprintf(并且可能更新您的问题以询问fprintf 而不是printf)。

    顺便说一句,您可能需要重新考虑使用名称log;这是<math.h> 中声明的标准函数的名称。

    反映您更新的问题,您可以通过直接调用fprintf 来打印log 内的时间戳:

    va_list(args);
    fprintf(f, "%s - ", now());
    va_start(args, format);
    vfprintf(f, format, args);
    

    【讨论】:

    • 谢谢;我已经编辑了我的问题以澄清 va_list 的问题。
    • @WChargin:我已经更新了我的答案。
    • 这个文档en.cppreference.com/w/cpp/utility/variadic/va_start 说你的format 必须是int(要解析的参数数量)。你如何解释这个差异?
    • 好的!!!!我知道了。第二个参数可以是 wtf。 va_start 只是搜索后面的内容。
    • @Sandburg:va_start 是一个宏,而不是一个函数。第二个参数是函数定义中, ... 之前的参数名称。在示例en.cppreference.com/w/cpp/utility/variadic/va_start 中,该参数恰好是int countva_start() 不看它的第二个参数的值,它只需要它的名字就知道从哪里开始扫描。
    【解决方案2】:

    您正在寻找的方法是vfprintf 或可能的vprintf(不清楚您的问题)

    这本质上是printf 的实现,它允许将va_list 作为参数显式传入。因此,在您的方法中,您可以为您的方法参数创建va_list 并将其转发到vfprintf

    void log(FILE* f, const char* format, ...) { 
      va_list args;
      va_start (args, format);
      vfprintf (f, format, args);
      va_end (args);
    }
    

    【讨论】:

    • vfprintf对应fprintfvprintf 对应于 printf。 (问题不清楚 OP 需要哪一个。)
    • @KeithThompson 好电话,已更新以包含两个参考文献
    • 谢谢;我已经编辑了我的问题以澄清 va_list 的问题。
    猜你喜欢
    • 2014-01-27
    • 2010-11-06
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多