Printing the structure using a single line in C?

偶尔善良 提交于 2019-12-07 20:31:29

Glibc allows you to establish your own format specifiers for printf and family to let you print UDTs, which would not otherwise be possible, through some extensions.

#include <stdio.h>
#include <printf.h> /* For PA_POINTER */

struct MyStruct
{
    int a;
    double b;
};

struct print_info;
int handler(FILE *stream, const struct print_info *i, 
        const void* const *args)
{
    const struct MyStruct *ptr = *( (const struct MyStruct**) (*args) );
    int rc = fprintf(stream, "a: %d, b: %f\n", ptr->a, ptr->b);

    return rc;
}

int print_arginfo (const struct printf_info *info, size_t n,
                      int *argtypes)
{
  if (n > 0)
    argtypes[0] = PA_POINTER;
  return 1;
}

int main(void)
{
    struct MyStruct s = {55, -3.14};
    /* We're gonna use the M specifier */
    int spec = 'M';
    int rc = register_printf_function(spec, handler, print_arginfo);

    if (rc != 0)
        return 1;

    printf("%M", &s);

};

You may find the documentation here.

First of all, the code probably wouldn't compile. You have defined ABC1 to be a typedef of the ABC struct. ABC1 is not a variable, so you cannot view the contents of ABC1.a.

Assuming you created a variable of type ABC1, you cannot "dump" the contents of the structure in a "logical" format using printf. The printf function receives a memory address and displays its contents based on the string given. The printf function cannot know the format of the structure if it only has a pointer to the memory (i.e. a bunch of bytes with no way of knowing what "type" of bytes).

No. Best solution would be to write a method like:

  1. void printABC(struct ABC*) or
  2. char* abcToString(struct ABC*) (and then print via %s).

Option 2 is probably better and can be used eg to write to file and so on.

No, printf() only has support for format specifiers for pre-defined data types, not for user defined data type (struct). Moreover, printf() also has no way to automatically learn the types of member variables of your struct.

You need to roll your own function to achieve the task you want.

Malek

Just like @john3136 said .

but here is an example for 1 .

void printABC(ABC1 *ABC) /* can also use 'struct ABC*' */
{
   printf("%d %c %ld",ABC->a,ABC->b,ABC->c);
   /* Equivalent to the below */
   /* printf("%d %s %ld",(*ABC).a,(*ABC).b,(*ABC).c); */
}

So now everytime you want to print the whole thing you just type something like

    ABC1 xyz;

    /* fill xyz here*/

    printABC(&xyz);

and It should type everything inside of ABC1 in one line.

If you are using a somewhat modern C compiler, you can use a type-generic macro:

#include <stdio.h>

typedef struct {
   int a;
   char b;
   long c;
} ABC;

// printf conversion specifiers:
#define CS(x)   \
  _Generic((x), \
    int:  "%d", \
    char: "%c", \
    long: "%ld")


int main (void)
{
  ABC abc = {1, 'a', 2};

  printf(CS(abc.a), abc.a); printf(" ");
  printf(CS(abc.b), abc.b); printf(" ");
  printf(CS(abc.c), abc.c); printf(" ");

  return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!