使用包含联合和类型成员的结构

Using a struct that contains a union and a type member

我正在尝试调试我正在编写的程序,该程序使用 C 中的 libvirt 库。

在程序的一部分中,我返回了以下结构:

struct virTypedParameter {
    char field[VIR_TYPED_PARAM_FIELD_LENGTH];
    int type;
    union {
        int i;
        unsigned int ui;
        long long int l;
        unsigned long long int ul;
        double d;
        char b;
        char *s;
    } value;
}

所以我有键、值和值类型。我希望能够通过将它们传递给函数来打印它们。

除了将类型放入 switch 语句并重定向到正确的 printf 语句之外,还有更简单的方法吗?我已经这样做了,它导致编译时弹出大量警告:

void printVirTypedParameter(virTypedParameter* param) {
    printf("Param type: %d\n", param->type);
    switch(param->type) {
        case 1: //int
            printf("%s : %d\n", param->field, param->value);
            break;
        case 2: //int unsigned
            printf("%s : %u\n", param->field, param->value);
            break;
        case 3: //long long int
            printf("%s : %ld\n", param->field, param->value);
            break;
        case 4: //long long unsinged
            printf("%s : %llu\n", param->field, param->value);
            break;
        case 5: //double
            printf("%s : %f", param->field, param->value);
            break;
        case 6: //boolean (character)
            printf("%s : %c", param->field, param->value);
            break;
        case 7: //string
            printf("%s : %s", param->field, param->value);
            break;
        case 8: //param last
            printf("END_PARAMS");
}

开关是实现它的方法。但是你应该使用适合你阅读的类型的联合成员,即如果你知道类型是 int,你应该使用 param->value.i。这应该避免任何警告。

例如:

switch(param->type) {
        case 1: //int
            printf("%s : %d\n", param->field, param->value.i);
            break;
        // ...
}

问题的评论涵盖了 OP 发布代码的明显问题。以下是已更正所有明显问题的代码示例。

#include <stdio.h>    // printf()

#define VIR_TYPED_PARAM_FIELD_LENGTH 30

enum VALID_TYPES
{
    INTEGER = 1,
    UNSIGNED_INTEGER,
    LONG_LONG_INTEGER,
    UNSIGNED_LONG_LONG_INTEGER,
    DOUBLE,
    CHAR,
    CHAR_POINTER,
    ALL_DONE
};

struct virTypedParameter
{
    char field[VIR_TYPED_PARAM_FIELD_LENGTH];
    //int type;
    enum VALID_TYPES type;
    union
    {
        int i;
        unsigned int ui;
        long long int l;
        unsigned long long int ul;
        double d;
        char b;
        char *s;
    } value;
};


// prototypes
void printVirTypedParameter( struct virTypedParameter* param);


void printVirTypedParameter( struct virTypedParameter* param)
{
    printf("Param type: %d\n", param->type);

    switch(param->type)
    {
        case INTEGER: //int
            printf("%s : %d\n", param->field, param->value.i);
            break;

        case UNSIGNED_INTEGER: //int unsigned
            printf("%s : %u\n", param->field, param->value.ui);
            break;

        case LONG_LONG_INTEGER: //long long int
            printf("%s : %lld\n", param->field, param->value.l);
            break;

        case UNSIGNED_LONG_LONG_INTEGER: //long long unsinged
            printf("%s : %llu\n", param->field, param->value.ul);
            break;

        case DOUBLE: //double
            printf("%s : %f\n", param->field, param->value.d);
            break;

        case CHAR: //boolean (character)
            printf("%s : %c\n", param->field, param->value.b);
            break;

        case CHAR_POINTER: //string
            printf("%s : %s\n", param->field, param->value.s);
            break;

        case ALL_DONE: //param last
            printf("END_PARAMS\n");
            break;

        default:
            printf( "found unexpected value in 'type' field: %d\n", param->type );
            break;
    }
}