C语言的宏

时间:2014-11-18 14:46:10

标签: c macros printf c99

我今天在gnu99上使用这个宏但是我想根据我的项目要求改变这个宏以支持-c99

 #define STR(format, ...) ({static char str[256]; (void)snprintf(str, 256, format, ##__VA_ARGS__); str;})

我可以将上面的宏转换成类似下面的内容,但我最后不知道如何处理str。

 #define STR(format, ...)                        
  do                                                                                                                         
    {                                                                                                                          
      static char str[256];                                                                    
      (void)snprintf(str, 256, format, ## __VA_ARGS__);                

    } while(0)

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

如果您希望sprintf的实现返回字符串(而不是字符数),请不要使用宏。使用短字符串的循环缓冲区编写一个简短函数:

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#define MAX_FMT 8

char *fmt(const char *format, ...)
{
    static char buf[MAX_FMT][256];
    static int nbuf;    
    va_list va;

    nbuf++;
    if (nbuf == MAX_FMT) nbuf = 0;

    va_start(va, format);
    vsnprintf(buf[nbuf], 256, format, va);
    va_end(va);

    return buf[nbuf];
}

int main()
{
    printf("%40s\n%40s\n%40s\n",
        fmt("%s: %d°C", "Copenhagen", 7),
        fmt("%s: %d°C", "Paris", 10),
        fmt("%s: %d°C", "Athens", 16));

    return 0;
}

您需要<stdarg.h>这里的功能来实现您自己的printf - 类功能。 vsnprintfsnprintf类似,只需要va_list

8 static个char缓冲区的循环缓冲区允许您在不分配的情况下返回字符串。当然,您一次最多可以使用8次fmt次来电,例如在一个printf电话中。

答案 1 :(得分:0)

您的想法太复杂了,只需将其设为一个表达式,并在外部定义缓冲区:

#define STR_USE static char str[256]
#define STR(format, ...) (snprintf(str, sizeof str, format, ## __VA_ARGS__), str)

在您可能想要调用STR_USE;的任何范围内使用STR,并像以前一样使用STR