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

时间:2017-09-04 16:04:10

标签: c printf libvirt

我正在尝试调试我正在使用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");
}

2 个答案:

答案 0 :(得分:5)

切换是这样做的方法。但是您应该使用适合您所读类型的联合成员,即如果您知道类型为param->value.i,则应使用int。这应该避免任何警告。

例如:

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

答案 1 :(得分:0)

该问题的评论涵盖了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;
    }
}