使用包含联合和类型成员的结构
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;
}
}
我正在尝试调试我正在编写的程序,该程序使用 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;
}
}