【问题标题】:Saving a Struct in a database file in C将结构保存在 C 中的数据库文件中
【发布时间】:2012-03-28 23:27:52
【问题描述】:

我想将一个结构保存到一个 db 文件(或 .txt,这仍然很重要!)但我遇到了以下问题。我想在结构中创建结构,如下面的代码。

typedef struct classes cl;
typedef struct attribute a;

struct classes{  \\where "a" is a type of struct
    a hunter;
    a channeler;
    a warrior;
    a rogue; };


struct human{     \\where "cl" is type of struct classes (
cl Borderlands;
cl Shienear;
cl Arafel;
cl Illian;
cl Tear;
cl Tarabon;
cl Andor;
cl TwoRivers;
cl Amandor;
cl Mayene;
cl Murandy;
};

问题是我是否有一个变量 构建人类数据 我必须保存树的所有分支(因为我认为它是我创建的树),还是只保存根,我是否保存整个结构?

附:请原谅我的写作方式,我没有编程经验

【问题讨论】:

    标签: c database struct tree save


    【解决方案1】:

    你应该像这样为每个结构创建保存方法:

    void save_h(human * h, FILE * stream)
    {
        save_cl(h->Borderlands,stream);
        save_cl(h->Shienear,stream);
        save_cl(h->Arafel,stream);
        save_cl(h->Illian,stream);
        save_cl(h->Tear,stream);
        save_cl(h->Tarabon,stream);
        ...
    }
    
    void save_cl(classes * cl, FILE * stream)
    {
        save_a(cl->hunter,stream);
        save_a(cl->channeler,stream);
        save_a(cl->warrior,stream);
        save_a(cl->rogueon,stream);
        ...
    }
    
    void save_a(attribute * a, FILE * stream)
    {
        ...
    }
    

    【讨论】:

    • 这个问题被标记为 C,而不是 C++。函数重载在 C 中不可用。
    • 还要注意这不是很灵活。将另一个结构类型添加到列表中会很痛苦。
    • 当然,它是不可扩展的。是否有可能以这种方式保存树,使其生长就像存储中的“附录”?
    【解决方案2】:

    如果您有没有指针、固定大小字段类型的简单结构并且不打算将此数据移动到其他机器上,您可以简单地将整个结构写入二进制文件,因为它在内存中具有线性表示。并以同样的方式读回它。否则,请阅读有关编组和解组数据的信息。如果你不理解这个概念,那么任何代码实际上都不是很有帮助。

    【讨论】:

      【解决方案3】:

      我会这样做:

      #define STRUCTFLAG 565719 // some random number
      
      // NOTE: This is based on the idea that sizeof(int) == sizeof(int *). 
      // If this is wrong, then make the type of variables such that 
      // sizeof(typeof variable) = sizeof(int *).
      struct basestruct {
          int flag; // when initialized, this has the value of STRUCTFLAG, so that we know it's a struct
          int size; // total size of the struct, in bytes. set when struct is created.
      
          // all other variables in the struct are either pointers to other structs or of the primitive type of the size 'int *'.
      }
      
      struct mystruct {
          int flag;
          int size;
      
          struct mystruct2 *variable1;
          struct mystruct3 *variable2;
      }
      
      int isStruct(const void *structAddr)
      {
          int *casted = (int *) structAddr;
          return casted[0] == STRUCTFLAG;
      }
      void saveStruct(FILE *file, const void *structaddr)
      {
          // make sure it's a struct
          if (isStruct(structaddr))
          {            
              int *casted = (int *) structaddr;
              fprintf(file, "%i\n", casted[0]); // print flag
      
              casted++; // skip 'flag';
      
              fprintf(file, "%i\n", casted[0]); // print size
              int numVariables = ((casted[0] / sizeof(int)) - 2);
      
              casted++;
      
              for (int i = 0; i < numVariables; i++)
              {
                  if (isStruct(casted + i))
                  {
                      saveStruct(file, casted + i);
                  }
                  else
                  {
                      fprintf(file, "%i\n", casted[i]);
                  }
              }
          }
          else
          {
              // report error
          }
      }
      

      祝你好运。你只问怎么保存!

      【讨论】:

      • sizeof(int) == sizeof(int *) 是一个可怕的假设。而且即使您将int 更改为intptr_t,您也无法在机器之间传输已保存的文件。
      • 我也不喜欢未声明的要求,即任何变量都不会碰巧具有值 STRUCTFLAG - 这会导致看起来随机且可能难以重现故障。
      • @interjay 是的,但这是我的第一个想法。虽然不可移植,但它是一个简单的实现,适用于较小的数据结构。
      • @interjay 也是如此。我并没有说这种方法没有它的警告和可能的错误,但它是一种灵活的低级解决方案。
      猜你喜欢
      • 2021-11-20
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      相关资源
      最近更新 更多