【问题标题】:How to create function like printf variable argument如何创建像 printf 变量参数这样的函数
【发布时间】:2011-10-25 06:11:39
【问题描述】:

我希望为我的日志记录实现一个类似 printf 的 api。它应该类似于调用 printf。 例如:

persistent_log(LogType0, "This is buffered writing %d", i);

我查看了变量参数的东西,但似乎我需要知道那里的参数的数量和类型。所以我在这方面需要更多帮助。

【问题讨论】:

  • 你想使用 C++0x 还是 C 风格的 va_args?
  • @awoodland , C 风格 va_args
  • 请注意,如果您使用va_args 方法,您将无法在编译时检查类型。如果您对 C++ 没问题,请使用 Boost.Format 或在模板上汇总解决方案。否则就接受缺乏类型安全。
  • 因为你想使用 va_args 我删除了 C++ 标签。

标签: c


【解决方案1】:

这是我发现对我很有效的过去项目的摘录。当然缺少一些初始化步骤。这里的关键是vfprintf 函数,它将处理打印各种参数的细节。

void _proxy_log(log_level_t level, const char *fmt, ...)
    __attribute__((format (printf, 2, 3)));

#define proxy_log(level, fmt, ...) _proxy_log(level, fmt"\n", ##__VA_ARGS__)

void _proxy_log(log_level_t level, const char *fmt, ...) {
    va_list arg;
    FILE *log_file = (level == LOG_ERROR) ? err_log : info_log;

    /* Check if the message should be logged */
    if (level > log_level)
        return;

    /* Write the error message */
    va_start(arg, fmt);
    vfprintf(log_file, fmt, arg);
    va_end(arg);

#ifdef DEBUG
    fflush(log_file);
    fsync(fileno(log_file));
#endif
}

【讨论】:

  • +1。没有太多人知道​​ GCC 的 __attribute__((format(...))) 工具可以添加编译时类型检查。
  • 好点。这是the documentation的链接
  • 帮助未来的旅行者:第一行,从'void _prox...'到'2,3)));'是所有函数声明并进入 *.h。 #define 在函数声明后几乎可以去任何地方,实现是最后一位。也许很明显,但我有一段时间感到困惑!
  • @Hamy #define 不是 function 声明,但这些行确实应该放在标题中。
【解决方案2】:

【讨论】:

  • 但我需要事先知道类型
  • 您可以通过自己检查格式字符串来了解这一点(如果您真的想玩得开心)。或者,这更容易,只需在您提取自定义参数后分派到 vfprintf。
【解决方案3】:

这是一个老问题,但这是我简化的基本解决方案,它完全模仿 printf 并且应该可以扩展到其他更具体的用途,它基本上是 Michael Mior 答案的通用版本:

#include <stdarg.h>

void print(const char* fmt, ...)
{
    va_list arg;
    va_start(arg, fmt);

    vprintf(fmt, arg); 
    //vprintf can be replaced with vsprintf (for sprintf behavior) 
    //or any other printf function preceded by a v

    va_end(arg);
}

(这似乎也适用于 c++,只是没有库)

【讨论】:

    猜你喜欢
    • 2010-09-06
    • 2015-03-28
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 2014-09-22
    • 2018-02-02
    相关资源
    最近更新 更多