如何在结构中存储MultiData值并与它们一起使用?

时间:2017-04-19 11:07:25

标签: c struct

我目前的代码:

#include <stdio.h>
#include <string.h>
/*
    struct Value {
       int typ;
       unsigned char vstring;
       int   vint;
       float  vfloat;
    };
*/
struct Value {
   int typ;
   /*
   type=1  ==> get vstring
   type=2  ==> get int
   type=3  ==> get float
   */
   union{
      struct{
         unsigned char *vstring;
      };
      struct{
         int   vint;
      };
      struct{
         float  vfloat;
      };
   }
};

void clear(Value vall){
   if(vall.typ == 1){
      delete(vall.vstring);
   }else if(vall.typ == 2){
      delete(vall.vint);
   }else{
      delete(vall.vfloat);
   }
}
int main()
{
   struct Value v;
   /////////////////////////////////////////////
   v.typ=1;
   strcpy( v.vstring,"C Programming/may this a very big utf-8 string!");
   /*
   strcpy( v.vint,4); 
   strcpy( v.vfloat,4.5);
   */
   /////////////////////////////////////////////
   printf( "ValueType : %d\n", v.typ);
   printf( "ValueString : %s\n", v.vstring);
   printf( "ValueInt : %d\n", v.vint);
   printf( "ValueFloat : %f\n", v.vfloat);
   return 0;
   Value copy=v;
   clear(copy);
   copy.typ=2;
   copy.vint=5;
}

但是这有bug,我不知道如何解决这个问题。

这有一个Value结构。在这里有(vstring,vint,vfloat)和typ中的值存储类型,以实现快速。

请帮我修复此代码。

我希望在array / map / hashmap中存储这个结构.... 坦克你。

2 个答案:

答案 0 :(得分:0)

您的代码的正确版本(但请注意注释!)是:

struct Value {
   int typ;
   /*
   type=1  ==> get vstring
   type=2  ==> get int
   type=3  ==> get float
   */
   union{
     unsigned char *vstring;
     int   vint;
     float  vfloat;
   } u;
};

void clear(struct Value *vall){
   if(vall->typ == 1){
      {free(vall->u.vstring); vall->u.vstring= 0;}
   }else if(vall->typ == 2){
      vall->u.vint=0;
   }else{
      vall->u.vfloat=0.0;
   }
}
int main()
{
   struct Value v;
   /////////////////////////////////////////////
   v.typ=1;
   v.u.vstring= malloc(strlen("C Programming/may this a very big utf-8 string!")+1);
   strcpy( v.u.vstring,"C Programming/may this a very big utf-8 string!");
   /////////////////////////////////////////////
   printf( "ValueType : %d\n", v.typ);
   printf( "ValueString : %s\n", v.u.vstring);
   printf( "ValueInt : %d\n", v.u.vint);        // <== there is no int in u
   printf( "ValueFloat : %f\n", v.u.vfloat);    // <== there is no float in u
   return 0;
   struct Value copy=v; // <== you cannot do this as you now use the memory of the vstring
   clear(&copy);    // <== this now releases the memory of vstring in both 'copy' and 'v'
   copy.typ=2;
   copy.u.vint=5;
}

答案 1 :(得分:0)

首先,您可以考虑使用union。它不是必需的,但会节省几个字节:

struct Value {
   int typ;
   /*
   type=1  ==> get vstring
   type=2  ==> get int
   type=3  ==> get float
   */
   union {
    unsigned char *vstring;  // Changed to char pointer!!
    int   vint;
    float  vfloat;
   };
};

接下来,当您复制字符串时,您需要分配空格:

const char *msg = "C Programming/may this a very big utf-8 string!";
struct Value v;
v.typ = 1;
v.vstring = malloc(strlen(msg) + 1);
strcpy(v.vstring, msg);
// strdup() does the same thing

当你清除时,你需要free那个记忆:

void clear(struct Value* vall){
   if (vall->typ == 1) {
      free(vall->vstring);
   }
   memset(vall, 0, sizeof(*vall));
}

最后,你可以使用枚举作为类型,而不是&#34;魔术数字&#34;:

enum VTYPE {VSTRING, VINT, VFLOAT};
typedef enum VTYPE vtype;

此外,还有一个帮助函数可以打印:

void print_value(struct Value *v)
{
    static const char *types[] = {"VSTRING", "VINT", "VFLOAT"};
    printf( "ValueType : %s\n", v->typ >= 0 && v->typ < 3 ? types[v->typ] : "ERROR");
    if (VSTRING == v->typ) {
        printf( "ValueString : %s\n", v->vstring);
    }
    else if (VINT == v->typ) {
        printf( "ValueInt : %d\n", v->vint);
    }
    else if (VFLOAT == v->typ) {
        printf( "ValueFloat : %f\n", v->vfloat);
    }
}

这里是整个事物的链接:http://ideone.com/ecy3qa

复制时,请务必复制字符串:

void copy_value(struct Value *source, struct Value *dest) {
    if (VSTRING == source->typ) {
        dest->vstring = malloc(strlen(source->vstring) + 1);
        strcpy(dest->vstring, source->vstring);
    }
    else if (VINT == source->typ) {
        dest->vint = source->vint;
    }
    else if (VFLOAT == source->typ) {
        dest->vfloat = source->vfloat;
    }
    dest->typ = source->typ;
}