Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在结构的动态排列中加载二进制文件的信息?_C_File_Struct_Binary_Fread - Fatal编程技术网

C 如何在结构的动态排列中加载二进制文件的信息?

C 如何在结构的动态排列中加载二进制文件的信息?,c,file,struct,binary,fread,C,File,Struct,Binary,Fread,我有一个二进制文件,其中包含以下序列: 0-9 char name[10]; 10-11 unsigned int n; 12-12+2x4n float coords[n][2]; 我需要把它加载到一个动态的结构数组中 我想在类型结构中保留文件中的所有信息: 所以我声明了一个如下的结构: typedef struct{ char name[10] unsigned int n; float coords[][2]; }sprites_t; 然后我制作了一个函数,将其加载到内存中:

我有一个二进制文件,其中包含以下序列:

0-9 char name[10];
10-11 unsigned int n;
12-12+2x4n float coords[n][2];
我需要把它加载到一个动态的结构数组中

我想在类型结构中保留文件中的所有信息: 所以我声明了一个如下的结构:

typedef struct{
char name[10]
unsigned int n;
float coords[][2];
}sprites_t;
然后我制作了一个函数,将其加载到内存中:

    size_t n = 0;
        sprites_t * s = malloc(sizeof(sprites_t)*INITIAL_PACKAGE);
        size_t reads;

       while((reads = fread(s + n,sizeof(sprites_t),INITIAL_PACKAGE,fi)) == INITIAL_PACKAGE ){
            sprites_t * aux = realloc(s,sizeof(sprites_t) * (n+INITIAL_PACKAGE));
            if (aux == NULL) {
                free(s);
                return EXIT_FAILURE;
            }
            s = aux;
            n += INITIAL_PACKAGE;
        }
n += reads;
我不能把这东西做得像我记忆中想要的那样多。因为在二进制文件中,我有一个“unsigned int n”,即具有坐标矩阵的行数,所以我的结构是灵活的。我怎么能读懂那本书?在此基础上,利用文件提供的信息完成结构的构建


我真的不知道我的代码是否正确。如果有人有另一种策略将信息加载到动态结构数组中,欢迎使用。

如果您的二进制
name
字段正好有10个字符长,那么您确实可以将其表示为
char[10]
,但您应该注意,除非它可靠地终止每个名称(因此实际上只有9个可用字符),将该数组视为包含C字符串是不安全的。如果希望能够将该名称视为字符串,请将数组声明长一个字符,并使用额外的空间确保内存中的副本正确终止

除此之外,您的结构似乎很好,您的结构对于灵活的数组成员来说似乎是一个合理的用例。但代码中的其他内容都是一场灾难。特别是

  • 您不能拥有具有灵活数组成员的对象数组,至少在FAM包含任何数据的情况下是这样。即使是动态数组在这里也没有意义,因为元素的大小不一致。如果您正计划查找他们叫什么名字

  • 您的代码对数据布局和表示做了很多假设,其中包括

    • 实现的内存中表示形式
      unsigned int
      与二进制文件的表示形式在大小、字节顺序和(非-)方面匹配填充位的使用。它可能与填充位匹配,因为它们很少使用。它可能与字节顺序相关。它可能与大小无关
    • 您的实现在
      name
      的结尾和
      n
      的开头之间没有任何填充来布局类型
      sprites\u t
      。您可能很幸运,但您需要这样做。特别是如果
      unsigned int
      的宽度超过两个字节,则结构布局确实包含pa的可能性很高迪丁
  • 灵活的数组成员是灵活的,因为程序可以为它们提供适当的空间,而不是它们自动伸缩。你似乎没有为你的数组成员提供任何空间,尽管你也没有阅读任何内容,所以这在表面上是毫无意义的

  • 那么总体的建议呢,

    • 使用链表或散列,而不是数组。对于前者,我将如下调整数据结构:

      typedef struct sprite {
          char name[11];        // includes space for a terminator
          uint16_t n;           // matches the data, except maybe in byte order
          struct sprite *next;  // to link these together into a list
          float coords[][2];    // flexible array of 2D coordinates
      } sprite_t;
      
    • 分别阅读每个精灵的
      name
      n
      coords
      成员

    • 最简单的方法是只在知道有多少组坐标后分配每个结构,所以可能

      char name[NAME_SIZE + 1] = { 0 };
      uint16_t n;
      if (fread(name, NAME_SIZE, 1, file) != 1) { /* handle EOF or I/O error ... */ }
      if (fread(&n, 2, 1, file) != 1) { /* handle EOF or I/O error ... */ }
      // swap n's byte order if appropriate ...
      sprite_t *sprite = malloc(sizeof(sprite_t) + n * sizeof(sprite->coords[0]));
      if (!sprite) { /* handle allocation failure ... */ }
      if (fread(sprite->coords, sizeof(sprite->coords[0]), n, file) != n) { /* handle EOF or I/O error ... */ }
      strcpy(sprite->name, name);
      sprite->n = n;
      append_to_linked_list(my_sprite_list, sprite);
      

    即使这样,仍然假定实现的类型表示形式
    float
    与文件中使用的表示形式匹配。如果不匹配,则您也需要修补它。这可能需要更多或更少的努力,而且“更多”如果尺寸不匹配,当然会出现这种情况,尽管可能性不大。

    非常感谢!这正是我需要的。真的,非常感谢。