是否有一个C预处理器宏来打印出一个结构?

时间:2011-09-26 19:15:29

标签: c struct macros c-preprocessor

据我所知,没有办法在 C 中打印出结构值。

即,这不会飞:

typedef struct {
    int a;
    double b;
} stype

stype a;

a.a=3;
a.b=3.4;

printf("%z", a);
相反,你必须说:

printf("a: %d\n", a.a);
printf("b: %f\n", a.b);

这似乎是一个完美的地方,您可以使用宏来为任意结构保存大量的输入。

C 预处理器是否足以执行此转换?

6 个答案:

答案 0 :(得分:7)

我会制作两个宏,如下:

#define STYPE_FMT "%d %f"
#define STYPE_MEMS(s) (s).a, (s).b

然后你可以做类似的事情:

printf("hello %s, stype: " STYPE_FMT "\n", "world", STYPE_MEMS(my_s));

这种方法优于结构的“打印功能”的原因是,您可以将宏用于您喜欢的任何printf - 族函数,并组合打印其他数据。

你可以变得更加漂亮,而是:

#define STYPE_FMT "%d %.*f"
#define STYPE_MEMS(s) (s).a, 6, (s).b
#define STYPE_MEMS_PREC(s, p) (s).a, (int)(p), (s).b

然后您可以使用默认精度或选择自定义精度。

答案 1 :(得分:4)

我认为最简单的解决方案(也许是最漂亮的)是使用函数来打印特定的结构。

void display_stype(stype *s)
{
    printf("a: %d\n", s->a);
    printf("b: %f\n", s->b);
}

如果您的结构发生了变化,您可以轻松地在一个地方适应您的代码。

答案 2 :(得分:3)

  

C预处理器是否足以执行此转换?

是的,是的,但是你必须在宏中重复整个结构声明,这会破坏目的。你可以这样:

STRUCT_PRINTF(
    a
  , ( int, a )
    ( double, b )
);

然后你需要一个相当复杂的宏实现,有很多很多辅助宏/函数。

答案 3 :(得分:2)

不,C预处理器主要是文本宏替换工具。它不知道C的类型和结构。

答案 4 :(得分:1)

您不能动态地或静态地(也不是在C ++中)迭代C中的struct成员。 C中没有反映。

因此,无法使预处理器执行此转换。

答案 5 :(得分:0)

你可以为此制作宏:

#define PRINT_MEMBER(M) do {printf(#M": %d\n", (int) M;} while(0)

然后像这样打印:

PRINT_MEMBER(a.a);
PRINT_MEMBER(b->b);

您可能想要定义其中的多个以涵盖不同类型(例如浮动,双打,打印为十六进制)。不幸的是,没有好的解决方法,因为C预备记录器没有关于什么类型的概念,例如你不能使用switch(typeof(M)) { case int: printf(.."%d"..; break; ...}之类的东西