【问题标题】:Loop through the file and read all records循环文件并读取所有记录
【发布时间】:2019-07-28 20:09:20
【问题描述】:

我有一个包含多条记录的文件。每条记录包含一个类型(一个二进制值数字)、len(再次bin值)和数据(长度为len的二进制值)。该文件包含多条记录。我想打印包含它自己的类型、长度和数据的每条记录。

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

typedef struct file_s {
  int16_t type;
  int32_t length;
  // Assumption: Each record is 16 bits
  // For a record size of 32 bits, use int32_t*
  int16_t* data;
} file_s;

int main() {
  file_s file;
  FILE* f = fopen("file.bin","r");
  if (f == NULL) {
    perror("Error");
    return 1;
  }
  fread(&file.type, sizeof(file.type), 1, f);
  fread(&file.length, sizeof(file.length), 1, f);
  file.data = malloc(file.length * sizeof(*file.data));


  fread(file.data, sizeof(*file.data), file.length, f);
  fclose(f);
  // Process the data
  /* ... */
  free(file.data);
  return 0;
}

如何遍历文件并打印每条记录。

【问题讨论】:

  • 关于:file.data = malloc(file.length * sizeof(*file.data)); 这是将记录的数据部分的总长度乘以指针的长度。可能不是你想要的。但是,file.length 包含数据记录中的总字节数,建议仅在调用 malloc() 时使用该值
  • 调用fread()时,一定要检查第三个参数和返回值,保证函数成功
  • 关于:fread(&amp;file.type, sizeof(file.type), 1, f); fread(&amp;file.length, sizeof(file.length), 1, f); file.data = malloc(file.length * sizeof(*file.data)); fread(file.data, sizeof(*file.data), file.length, f); 这只会读取第一条记录。此代码需要处于循环中,以便读取所有记录。在该循环中,在读取记录的所有部分后,然后使用printf() 打印出这些部分。注意:打印单个数据项可能需要另一个循环
  • 关于; return 1; 最好写成:exit( EXIT_FAILURE ); 注意exit()EXIT_FAILURE 都通过头文件公开:stdlib.h
  • OT:为了灵活性和易于阅读:最好将结构定义与该结构的 typedef 分开

标签: c file loops struct binary


【解决方案1】:

思路是每次检查fread的返回值,如果返回值小于expect,则检查feof()是否到达文件末尾。您可以通过谷歌“man fread”和“man feof”查看手册页。您可以使用 do while 循环来循环文件。

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int feof(FILE *stream);

类似:

  while(1) {
      size_read = fread(&file.type, sizeof(file.type), 1, f);
      if(size_read!=1 || feof(f))
          break;
      fread(&file.length, sizeof(file.length), 1, f);
      //do the same check
      file.data = malloc(file.length * sizeof(*file.data));

      fread(file.data, sizeof(*file.data), file.length, f);
      //do the same check, remember to free the memory!
  }

【讨论】:

  • 您说要使用do...while 循环,但您的答案是使用while 循环
  • 每次循环调用malloc(),但在循环结束时没有调用free(),这意味着分配的内存指针:file.data在每个循环中都被覆盖。导致通过循环的每次迭代都发生不可恢复的内存泄漏
  • 你期望的太高了!代码示例中的注释清楚地提醒释放内存!确切的问题是“我如何遍历文件并打印每条记录。”
猜你喜欢
  • 2015-07-02
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2019-12-22
相关资源
最近更新 更多