我正在try 编写一个基本的宏,如下所示:

#define USER_ERROR(fmt, ...) { \
    fprintf(stderr, "ERROR %s(): %s\n", __func__, fmt, ##__VA_ARGS__); \
} \

我的理想用法是:

USER_ERROR("something went wrong %s %s", more_detail, even_more_detail);

不幸的是,我收到一个编译错误:

格式字符串未使用数据参数

我知道单%s只处理一个参数,但如何才能使格式化程序变得多样呢?

推荐答案

您可以使用字符串常量连接将格式字符串与宏中的内置字符串组合在一起:

#define USER_ERROR(fmt, ...) \
    fprintf(stderr, "ERROR %s(): " fmt "\n", __func__, ##__VA_ARGS__);

int main()
{
    char more_detail[]="abc", even_more_detail[]="def";
    USER_ERROR("something went wrong %s %s", more_detail, even_more_detail);
    return 0;
}

输出:

ERROR main(): something went wrong abc def

这也有一个副作用,即确保格式字符串是字符串常量,因为格式字符串可能由用户控制可能会导致安全问题.

C++相关问答推荐

错误:C中需要参数声明符

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

限制不同类型的限定符

为什么memcpy进入缓冲区和指向缓冲区的指针工作相同?

为什么此共享库没有预期的依赖项?

使用%f格式说明符打印整数值

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

使用ld将目标文件链接到C标准库

从不兼容的指针类型返回&&警告,但我看不出原因

将非连续物理内存映射到用户空间

在运行时判断C/C++指针是否指向只读内存(在Linux操作系统中)

*S=0;正在优化中.可能是GCC 13号虫?或者是一些不明确的行为?

存储和访问指向 struct 的指针数组

C:面筋蛋白';为什么不刷新窗口?

我错误地修复了一个错误,想了解原因

gdb - 你能找到持有内部 glibc 锁的线程吗?

使用 strtok 多次分割一个字符串会导致意外行为

C/C++编译器可以在编译过程中通过按引用传递来优化按值传递吗?

如何在Linux上从控制台左上角开始打印文本?