如何读取整数的二进制文件?

How can i read a binary file of integers?

提问人:mkkuuu 提问时间:10/16/2023 更新时间:10/16/2023 访问量:65

问:

我是 c 的新手,我试图从整数的二进制文件中获取整数数组,我不明白如何修复我的函数。

int test_read(const char* filename) {
    FILE *fp;
    fp = fopen(filename, "r");

    if (fp == NULL) {
        printf("Erreur lors de l'ouverture du fichier.\n");
        return 0;
    }

    /*fseek(fp,0L,SEEK_END);
    if((ftell(fp)%4) != 0){ printf("SEG FAULT");return 0;};
    fseek(fp,0L,SEEK_SET);*/

    int* tab = new_tab(100);
    int k = 0;
    while (fgetc(fp) != EOF) {
        int a=0;
        for(int i=0;i<sizeof(int);i++){
            a = (a<<8|fgetc(fp));
        }
        tab[k]=a;
        k+=1;
    }
    print_tab(tab);
    fclose(fp);
    return 1;

int *new_tab(int size){
    if(size>0) {
        int *tab = malloc((size)*(sizeof(int)));
        for (int i = 0; i < size; i++) {
            tab[i] = i + 1;
        }
        return tab;
    }
    else{
        printf("erreur");
        return NULL;
    }
}


int main(void) {
    test_read("data/100");
}

data/100 包含 100 个整数作为二进制。

这就是回报我:

 -1114095639  120378042  -173307421  -1962110490  -19512031  -1843036650  86438161  -903216896  1578651565  1947564876  1435467956  2121161697  -817940757  -1854549618  16834356  -486212261  -1182672308  -660020925  -2020002901  640444696  -1  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100

我知道我在获取整数的途中遇到了问题,但我无法得到它。 如果有人能帮我谢谢

C 二进制文件

评论

0赞 mkkuuu 10/16/2023
对不起,如果问题已经得到回答,但我不明白这些答案。
4赞 Weather Vane 10/16/2023
第一步是在 bianry 模式下打开文件: .然后丢弃读取的数据字节。我建议使用 来读取每个整数:fp = fopen(filename, "rb");while (fgetc(fp) != EOF)freadwhile(fread(...))
1赞 Weather Vane 10/16/2023
我建议你从两个或三个整数的文件开始,而不是 100。然后,您可以更轻松地发布数据和阅读的内容。
0赞 mkkuuu 10/16/2023
谢谢,我会尝试使用较少的整数,但类似的东西在没有相同地址的情况下返回相同的内容。int* 选项卡 = new_tab(100);for(int k=0;K<100;k++){ fread(tab,sizeof(int),100,fp print_tab);
1赞 Weather Vane 10/16/2023
fread(tab,sizeof(int),100,fp)读取 100 ints。没有任何循环。

答:

0赞 erik258 10/16/2023 #1

这个最小示例用于将整数 0 到 9 的平方的二进制表示形式写入临时文件。然后,它用于将文件位置返回到开头,然后将 10 个整数放入新分配的内存中。fwriterewindfread

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

int main() {
  FILE* f = tmpfile();
  if(f == NULL) {
    perror("Failed to open temp file");
    return 1;
  }
  for(int i = 0; i < 10; i++) {
    int j = i * i;
    if(1 != fwrite(&j,sizeof(int), 1, f)) {
      perror("Failed to write an int to file");
      return 2;
    }
  }
  rewind(f);
  int* ints = malloc(sizeof(int) * 10);
  if(10 != fread(ints, sizeof(int), 10, f) ){
    perror("Failed to read 10 ints");
    return 3;
  }
  for(int i = 0; i < 10; i++) {
    printf("%d\n", ints[i]);
  }
}
1赞 oreodave 10/16/2023 #2

首先,我强烈建议您查看 fwritefread 的手册页。他们提供有用的信息并给予 关于用法的明确示例。我认为它们是所需的功能 让它工作。

打开二进制文件时应使用二进制模式。这是 非常重要,因为在 Windows 上,两者之间存在不同的行为 正常读取模式和二进制读取模式(有关原因,请参阅此答案)。 所以特别是,是正确的 本例的代码。FILE *fp = fopen(filename, "rb");

要直接从流中读取整数(即二进制):

int c = 0;
fread(&c, sizeof(c), 1, fp);

比如说,要读取 100 个整数:

int nums[100];
for (int i = 0; i < 100; ++i)
{
   fread(nums + i, sizeof(nums[0]), 1, fp);
}

另一种方式,很好看,但肯定不那么可读 IMO是:

int nums[100];
fread(nums, sizeof(nums[0]), 100, fp);

请注意,我没有进行错误检查。这是对 读者。

(小注意:我假设二进制文件 整数是由您用来读取的同一台计算机编写的(或 至少相同的架构),情况可能就是这样。这是为了 确保计算机上的整数大小与 文件编写器,二进制文件中整数的字节序 与您的计算机相同:如果出现以下情况,您可能会遇到一些奇怪的错误 这不是真的)

评论

0赞 mkkuuu 10/16/2023
好的,我解决了我所有的问题,谢谢
0赞 erik258 10/16/2023
FWIW、二进制和文本模式在 Posix 系统(Unix、Linux 等)上是等效的。在这种情况下,Windows 像往常一样很奇怪。