fprintf() 的跨平台宏包装器

标签 c visual-studio gcc c-preprocessor variadic-macros

是否有一种跨平台方法来包装 fprintf() ,以便我可以拥有一个简单的日志记录功能,将日志转储到文件或控制台,并利用简单的 C printf() 样式格式字符串和参数列表?

现在,我正在做这样的事情:

#define logIssue(fmt, ...) do { \
    fprintf(stderr, "MY_PREFIX:%s:%s:%d > " fmt "\n", __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
} while(0);

这适用于 GCC,如果我删除前导 ##,它也适用于 GCC Visual Studio 2005(是的,我必须让它在 VS2005 上运行)到 2015 年),但在 2012 年之前的 Visual Studio 版本中,当我实际上没有变量参数列表时,它会失败,即:

logIssue("Problem with test#%d.", iTestID); // Succeeds
logIssue("General problem."); // Fails

我已经详细阅读了这个问题,包括以下内容:

这些提供了潜在的解决方案,但我似乎无法将它们与我的 fprintf() 宏集成。

是否有任何简单的方法可以通过宏技巧让这个包装宏在 Linux (GCC) 和 Windows(MSVC 2005 及更高版本)中工作?

谢谢。

最佳答案

不需要扩展:

#define logIssue(...) do {      
    fprintf(stderr, "MY_PREFIX:%s:%s:%d > ", __func__, __FILE__, __LINE__);
    fprintf(stderr, __VA_ARGS__ );
    fputs( "", stderr);
} while(0)

这适用于两个调用,并且符合 C99:

logIssue("Problem with test#%d.", iTestID);
logIssue("General problem.");

关于fprintf() 的跨平台宏包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35160023/

相关文章:

c++ - 沉默 gcc 的 Wunused-variable

c# - List<> 不在 DispatcherTimer 中更新

c# - 菜单的键盘顺序快捷方式

c - 打印字符数组垃圾

c - 子进程是否执行这两个打印?

visual-studio - 免费源代码管理

c++ - 共享对象(.so)静态链接并打开其他共享对象,它们之间是否共享静态库代码?

c++ - 期望 const std::string & 的函数的链接器错误

c - 我需要一种在 C 中两次读取 float 的方法。每次都以 <Ctrl>-d 结束

c - 如何将 "dump"函数写入文件?