38

I am interested in printing the structure fields .

Typedef struct
{
   UINT32 thread_id;
   BOOL   is_valid;
}T_THREAD;

Is there a way in "C" language to print the contents of a structure, something like

ex: print (T_THREAD) and output should be like

Contents of a structure T_THREAD are 
  thread_id
  is_valid
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
user3555115
  • 546
  • 1
  • 4
  • 11
  • 2
    Do you want to print the values of a specific instance or the layout of the general structure? (Though the answer is no either way, you have to do it yourself) – user45891 Dec 23 '16 at 16:06
  • 1
    I would like to print the layout of the general structure. If i add some more fields to the struct, then my printf should be able to print the new added one as well. – user3555115 Dec 23 '16 at 16:09
  • The answers to this question could be useful in some cases: https://stackoverflow.com/questions/34390799/printing-the-structure-using-a-single-line-in-c – nielsen May 16 '23 at 09:06

6 Answers6

31

What you're looking for is reflection. Java and other virtual languages has reflection so you can print out the variable names and function names for any given class. Because the compiler builds these reflection functions automatically.

C does not have reflection. You must do everything manually.

Dellowar
  • 3,160
  • 1
  • 18
  • 37
9

As for your structure, the function would look something like this..

// st_name is the name of the struct
void print(T_THREAD *st, const char *st_name)
{
    printf("Contents of structure %s are %lu, %d\n", st_name, st->thread_id, st->is_valid);
}
Hawk
  • 788
  • 1
  • 6
  • 18
7

No, there is no standard/ pre-defined way of achieving what you want.

Yes, however, you may write your own function, which has knowledge of the particular structure element values to be printed, and then, with a single call to the function with a particular instance of the structure variable, you can get all the values of all the members get printed. Something like

T_THREAD var;

my_print(var);  //my_print() is the function you'll roll out

should be able to print the values.

However, please note, this does not allow you to print the variable names in any ways, only "values".

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
4

There is no way you can print all the structure elements with a single printf statement. In C you have to print them all out manually. Here is an example of creating two structure members and printing them out:

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

typedef struct {
    char *name;
    int thread_id;
    bool is_valid;
}T_THREAD;

int
main(void) {
    T_THREAD T1 = {"T1", 123, 1};
    T_THREAD T2 = {"T2", 456, 0};

    printf("\nContents of a structure %s are:\n", T1.name);
    printf("thread_id: %d\n",T1.thread_id);
    printf("is_valid: %d\n", T1.is_valid);

    printf("\nContents of a structure %s are:\n", T2.name);
    printf("thread_id: %d\n",T2.thread_id);
    printf("is_valid: %d\n", T2.is_valid);

    return 0;
}

Output:

Contents of a structure T1 are:
thread_id: 123
is_valid: 1

Contents of a structure T2 are:
thread_id: 456
is_valid: 0

Alternatively, you can create a function to do this also:

int
main(void) {
    T_THREAD T1 = {"T1", 123, 1};
    T_THREAD T2 = {"T2", 456, 0};

    print_struct_elements(&T1);
    print_struct_elements(&T2);

    return 0;
}

void
print_struct_elements(T_THREAD *T) {
    printf("\nContents of a structure %s are:\n", T->name);
    printf("thread_id: %d\n",T->thread_id);
    printf("is_valid: %d\n", T->is_valid);
}
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
  • 3
    Sure you can print it all in one call to printf: `printf("\nContents of a structure %s are:\nthread_id: %d\nis_valid: %d\n", T->name, T->thread_id, T->is_valid);` – simon Dec 23 '16 at 17:09
2

I believe that debuggers such as GDB can do the job, but it's a little more work than printf.

  1. compile the C file with debug symbols. "gcc -o test -g test.c"
  2. attach the executable to GDB. "gdb test"
  3. run GDB to the line where you wish to print the struct. (eg. https://visualgdb.com/gdbreference/commands/print)
  4. print struct. "p structA"

Assuming I have the following code,

78    typedef struct
79    {
80       int thread_id;
81       int is_valid;
82    }T_THREAD;
83
84    T_THREAD tThread = { 0 } ;

printing the struct in GDB will be like this.

gdb -o test -g test.c
gdb test
(gdb) break 85
(gdb) run
(gdb) p tThread
$1 = {thread_id = 0, is_valid = 0}

There are lots of GDB tutorials online. Here is one that could help you get started. https://condor.depaul.edu/glancast/373class/docs/gdb.html

Simon
  • 51
  • 3
1

One way of doing this would be using x-macros. Though not as pretty compared to reflection that is built into a language. Using macro does make the code a little harder to read, but it is pretty straight forward.

#include <stdio.h>
#include <stdint.h>

#define HDR_STRUCT_FIELDS       \
  FLD(0, Field_1, uint32_t, 3)  \
  FLD(1, Field_2, uint16_t, 4)  \
  FLD(2, Field_3, uint8_t,  5)

#define FLD(idx, fld, dt, initVal)   dt fld;
typedef struct 
{
    HDR_STRUCT_FIELDS
} HdrData_t;
#undef FLD

#define FLD(idx, fld, dt, initVal)   .fld = initVal,
HdrData_t HeaderData = 
{
   HDR_STRUCT_FIELDS
};
#undef FLD


#define QUOTE(field)     #field
#define FLD(idx, fld, dt, initVal)   [idx] = QUOTE(fld),
const char* HeaderDataName[] = 
{
   HDR_STRUCT_FIELDS
};
#undef FLD


int main()
{   
    #define FLD(idx, fld, dt, initVal)   printf("%s = %d\n", HeaderDataName[idx], HeaderData.fld);
    HDR_STRUCT_FIELDS
    #undef FLD

    return (0);
}

Another method where the ordering of the field is not as important would be the following which uses a structure and initializing the structure.

#include <stdio.h>
#include <stdint.h>

#define HDR_STRUCT_FIELDS    \
  FLD(Field_1, uint32_t, 3)  \
  FLD(Field_2, uint16_t, 4)  \
  FLD(Field_3, uint8_t,  5)

#define FLD(fld, dt, initVal)   dt fld;
typedef struct
{
    HDR_STRUCT_FIELDS
} HdrData_t;
#undef FLD


#define FLD(fld, dt, initVal)   .fld = initVal,
HdrData_t HeaderData =
{
   HDR_STRUCT_FIELDS
};
#undef FLD


#define FLD(fld, dt, initVal)   const char *fld;
typedef struct
{
   HDR_STRUCT_FIELDS
} HdrDataFldString_t;
#undef FLD

#define STRINGIZE(field)        #field
#define FLD(fld, dt, initVal)   .fld = STRINGIZE(fld),
HdrDataFldString_t  HdrDataFldString =
{
   HDR_STRUCT_FIELDS
};
#undef FLD


int main()
{
    #define FLD(fld, dt, initVal)   printf("%s = %d\n", HdrDataFldString.fld, HeaderData.fld);
    HDR_STRUCT_FIELDS
    #undef FLD

    return (0);
}
lordhog
  • 3,427
  • 5
  • 32
  • 43