我试过这个:
#define format(f, ...) \
int size = strlen(f) + (sizeof((int[]){__VA_ARGS__})/sizeof(int)) + 1); \
char *buf = malloc(size); \
snprintf(buf, size, f, __VA_ARGS__); \
buf
但它会返回很多语法错误。我该怎么做呢?
答案 0 :(得分:3)
C宏不是函数,而是1:1替换。所以如果你想像这样使用你的宏:
mystring = format("%d", 5);
你明白了:
mystring = int size = strlen(f) + (sizeof((int[]){5})/sizeof(int)) + 1); \
char *buf = malloc(size); \
snprintf(buf, size, f, 5); \
buf;
这没有任何意义。在你的情况下,你最好定义一个内联函数,在一个体面的编译器的性能方面不应该更差。
如果确实必须是一个宏并且你在GCC上,你可以使用复合语句来实现你的目标。它允许您执行此操作:mystring = ({ statement1, statement2, ..., statementN})
将执行本地范围内的所有语句,然后将statementN
分配给mystring
。但是它会使你的代码变得不可移植并且无法进行调试。
所以你去了,但请不要在实际应用中使用它:
#define format(f, ...) \
({ int size = snprintf(NULL, 0, f, __VA_ARGS__) + 1;\
char * buf = malloc(size);\
snprintf(buf, size, f, __VA_ARGS__); buf; })
我很认真。不要使用它。使用内联函数。您还可以使用va_arg
和va_start
在正常函数中使用可变参数:
inline char * format(f, ...) {
va_list args;
va_start(args, f);
int size = vsnprintf(NULL, 0, f, args) + 1;
char * buf = malloc(size);
vsnprintf(buf, size, f, args);
return buf;
}
答案 1 :(得分:0)
如果您在没有参数的情况下使用它,则应键入
snprintf(buf, size, f, ## __VA_ARGS__);
代替;否则它不会截断尾随的逗号。
此外,如果您想使用格式字符串,则无法确定strlen(format) + length of every other elements
实际上是您获得的大小。你必须做出一个假设,然后使用一个安全的功能。
使用这种宏语法也无法返回值。但是,使用GNU扩展是可能的。请参阅下面的修改后的答案。
另外,你想用
做什么sizeof((int[]){__VA_ARGS__}
?它根本不好。您无法找到可变参数列表的大小。
尝试这样的事情:
#define format(f, ...) \
({
char *buf = malloc(4096); \
snprintf(buf, 4096, f , ## __VA_ARGS__); \
buf
})
希望这有帮助。
答案 2 :(得分:0)
不知道你要用第一行做什么。您似乎正在尝试计算参数的数量,但之后您将其传递给malloc
并使用malloc
的返回值作为大小..?!
为snprintf
分配空间的正确方法是首先使用缓冲区指针调用snprintf
并将大小设置为零,然后检查返回值。在返回值中添加一个(对于空终止)将为您提供分配所需的大小并传递给第二个snprintf
调用。
另外,不要试图用宏来做这件事;使用函数和vsnprintf
。