Is there a C preprocessor macro to print out a str

2019-06-07 14:32发布

As far as I can tell, there's no way to print out a struct value in C.

i.e., this doesn't fly:

typedef struct {
    int a;
    double b;
} stype

stype a;

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

printf("%z", a);

instead you have to say:

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

This seems like a perfect place where you could use a macro to save a vast amount of typing for arbitrary structs.

Is the C preprocessor powerful enough to perform this transformation?

6条回答
聊天终结者
2楼-- · 2019-06-07 14:54

You could make macro for this:

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

and then print it like this:

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

You might wanna define multiple of these to cover different types (e.g. floats, doubles, print as hex). Unfortunately there is no good workaround for this as C preprecossor has no notion of what types are, e.g. you can't use something like switch(typeof(M)) { case int: printf(.."%d"..; break; ...} .

查看更多
看我几分像从前
3楼-- · 2019-06-07 15:01

No, the C preprocessor is mostly a textual macro replacement tool. It doesn't know about types and structures of C.

查看更多
欢心
4楼-- · 2019-06-07 15:04

Is the C preprocessor powerful enough to perform this transformation?

Yes, it is, but then you have to repeat the entire struct declaration within the macro which kind of defeats the purpose. You could have something like this:

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

and then you would need a pretty complex implementation of such macro, with lots and lots of helper macros/functions.

查看更多
老娘就宠你
5楼-- · 2019-06-07 15:06

I think that the simplest solution (and maybe the most beautiful) is to use a function to print your specific struct.

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

If your struct changed, you can adapt in one place your code easily.

查看更多
我命由我不由天
6楼-- · 2019-06-07 15:16

You cannot iterate on struct members in C, either dynamically or statically (nor in C++). There is no reflection in C.

Thus, there is no way to make the preprocessor perform this transformation.

查看更多
闹够了就滚
7楼-- · 2019-06-07 15:20

I would make two macros, like this:

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

Then you can do something like:

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

What makes this approach superior to a "print function" for the structure is that you can use the macros with any of the printf-family functions you like, and combine printing of other data.

You could get even fancier and instead do:

#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

and then you can use the default precision or choose a custom precision.

查看更多
登录 后发表回答