Printing the structure using a single line in C?

2019-06-06 03:15发布

问题:

Is there any possible way in C (by using any function or any such kind) so that we can print the contents in a structure of different datatypes using a single line? Say for eg:

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

To print this we need to write: printf("%d %s %ld",ABC1.a,ABC1.b,ABC1.c)

Any other method so that i can print like printf("????",????ABC1)??

回答1:

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.



回答2:

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).



回答3:

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.



回答4:

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.



回答5:

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.



回答6:

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;
}


标签: c structure