在C中打印结构字段和值

时间:2016-12-23 16:03:01

标签: c printf structure

我对打印结构字段感兴趣。

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

是否有一种方法用“C”语言来打印结构的内容,如

ex:print (T_THREAD),输出应该像

Contents of a structure T_THREAD are 
  thread_id
  is_valid

6 个答案:

答案 0 :(得分:10)

您正在寻找的是反思。 Java和其他虚拟语言具有反射,因此您可以打印出任何给定类的变量名称和函数名称。因为编译器会自动构建这些反射函数。

C没有反射。你必须手动完成所有事情。

答案 1 :(得分:4)

不,没有标准/预定义的方式来实现您的目标。

是的,但是,您可以编写自己的函数,该函数了解要打印的特定 结构元素值 ,然后只需调用一次函数具有结构变量的特定实例,可以获得所有成员的所有值的打印。像

这样的东西
T_THREAD var;

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

应该能够打印这些值。

但请注意,此允许您以任何方式打印变量 names ,仅限“值”。

答案 2 :(得分:4)

至于你的结构,函数看起来像这样......

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

答案 3 :(得分:3)

您无法使用单个printf语句打印所有结构元素。在C中,您必须手动打印它们。以下是创建两个结构成员并将其打印出来的示例:

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

输出:

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

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

或者,您也可以创建一个函数来执行此操作:

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

答案 4 :(得分:2)

我相信像 GDB 这样的调试器可以完成这项工作,但它比 printf 多一点工作。

  1. 使用调试符号编译 C 文件。 "gcc -o test -g test.c"
  2. 将可执行文件附加到 GDB。 “gdb 测试”
  3. 运行 GDB 到您希望打印结构的行。 (例如https://visualgdb.com/gdbreference/commands/print
  4. 打印结构。 "p structA"

假设我有以下代码,

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

在 GDB 中打印结构体将是这样的。

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

网上有很多 GDB 教程。 这是一个可以帮助您入门的方法。 https://condor.depaul.edu/glancast/373class/docs/gdb.html

答案 5 :(得分:0)

一种方法是使用x-macros。尽管与语言内置的反射相比,它不那么漂亮。使用宏确实会使代码更难阅读,但是很简单。

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

字段排序不那么重要的另一种方法是使用结构并初始化该结构。

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