C语言如何将可变参数列表传给另外一个函数?

如题,我想通过debug,info,warning这些函数来打印对应等级的日志,它们最终调用的都是_logging函数,并在logging函数中统一进行vsnprintf,我要怎么才能把可变参数列表传过去?还是说不支持这样的操作?

public:
void debug(const char *def_name, const char *format, ...)
void info(const char *def_name, const char *format, ...)
private:
void _logging(int level, const char *def_name,  const char *format, ...)
如果不这么做,就得把使用vsnprintf的几行代码重复写到每一个独立函数中

目前百度到如下办法,无作用

void warning(const char *def_name, const char *format, ...)
{
    // 获取可变参数列表
    va_list ap;
    va_start(ap, format);
    _logging(LOG_WARINING, def_name, format,ap);
    va_end(ap);
}

直接调用logging函数的能正常打印,调用warning函数无法正常打印。如下,第一行是直接调用warning的,没有打印出消息内容

[23-04-27 19:59:35] WARN | 1682596775 | test | 
[23-04-27 19:59:35] WARN | 1682596775 | test | 这是一个测试而已

感谢大佬的回答,在这里贴上完整可用的代码【也可以去我的github看】

public:
    template <typename... Args>
    void error(const char *def_name, const char *format, Args &&...args) {
        _logging(LOG_ERROR, def_name, format, std::forward<Args>(args)...);
    }
    //其他的都是对这项的copy,只修改传入的log level
private:
    void _logging(size_t level, const char *def_name, const char *format, ...)
    {
        assert(level >= LOG_DEBUG && level <= LOG_FATAL);
        if (level < _level)
        { // 低于定义的等级,不打印
            return;
        }
        va_list ap;
        va_start(ap, format);
        vsnprintf((char *)_log_info.c_str(), _log_size - 1, format, ap);
        va_end(ap);
        // 根据日志等级选择打印到stderr/stdout
        // 超过了error的日志,要使用stderr打印
        FILE *out = (level >= LOG_ERROR) ? stderr : stdout;
        def_name = def_name == nullptr ? "unknow" : def_name; // 判断defname是否为空
        // 格式化打印到文件流中
        fprintf(out, "%s | %s | %s\n",
                    log_level[level],
                    def_name,
                    _log_info.c_str());
    }

测试

void LogTest()
{
    vod::Logger _log;
    _log.info("test","%s","this in info");
    _log.warning("test","%s %d","this is warning",333);
    _log.error("test","%s","this is err");
    _log.fatal("test","%s","this is fatal!!!");
}
INFO | test | this in info
WARINING | test | this is warning 333
ERROR | test | this is err
FATAL | test | this is fatal!!!
阅读 1.9k
1 个回答

c++ 中我们一般使用 variadic templates,除非你要和 c 库兼容

template <typename... Args>
void warning(const char *def_name, const char *format, Args &&...args) {
    _logging(LOG_WARINING, def_name, format, std::forward<Args>(args)...);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏