gpt4 book ai didi

c - 使用 C 无法读取 4 字节整数 (Int32) 文件

转载 作者:行者123 更新时间:2023-11-30 14:32:55 25 4
gpt4 key购买 nike

我的 C 代码(使用 VS 2015)无法完全读取包含多个 4 字节有符号整数 (int32) 的文件,而二进制查看器程序显示文件中的数据没有问题(图 1)。我尝试了几种读取数据文件的方法,结果相似。我的问题只是下面的示例代码中有什么不正确的地方?如果代码没有问题,那么数据文件可能有什么问题?

如果有人有时间和兴趣检查它,我在下面提供了示例数据文件的链接。在两个代码示例(如下)中,读取在整数 78 处停止,根据二进制查看器,该值 = 26。

示例代码1:

typedef signed __int32 INT32;

FILE *fp = NULL;
INT32 k;
int i=0;

fp = fopen(myfilePath, "r");

while(!feof(fp))
{
fread(&k,sizeof(INT32),1,fp);
printf("a[%d] = %d\n",i,k);
i++;
}
fclose(fp);

示例代码2:

typedef signed __int32 INT32;

FILE *fp = NULL;
long sz=0;
INT32 k;
int i=0

fp = fopen(myfilePath, "r");
// find the size of the file
fseek(fp, 0L, SEEK_END);
sz = ftell(fp)/4; // store the Int32 data count
rewind(fp);

for(i=0;i<sz;i++)
{
fread(&k,sizeof(INT32),1,fp);
printf("a[%d] = %d\n",i,k);
}
fclose(fp);

Binary Viewer Reads the entire file correctly and indicates (in yellow) where C stops reading the file

Link to example data file. Size: 3,572 bytes. Contains 893 Int32 values

感谢您的帮助!

最佳答案

您的输入文件中的内容稍微偏离了目标。您的输入文件提供文件中包含的 32 位整数的数量作为第一个值。您只需读取第一个整数即可知道需要为其余值分配多少存储空间。

标准 C 库不是使用 typedef 来表示有符号 32 位整数,而是提供了 stdint.h header ,其中包含所有精确宽度类型,包括有符号32 位类型已作为 int32_t 提供。 inttypes.h header 提供了用于打印和读取精确宽度类型的宏(例如 PRId32 用于打印,其中 d 可以是 u 无符号、x 十六进制、o 八进制或 i 整数,例如 SCNd32 用于扫描f)

因此,您真正需要做的就是打开文件进行读取(使用 "rb" 作为可移植性模式,'b' 不这样做任何内容,并且是为了 C89 兼容性而提供的)您打开文件并将第一个 32 位值读入变量。这会告诉您后面有多少个 32 位值 - 并使文件位置指示器准备好读取剩余的值,例如

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

int main (int argc, char **argv) {

int32_t *a = NULL, nint = 0; /* pointer and no. of int */
/* use filename provided as 1st argument ("000002.dat" by default) */
FILE *fp = fopen (argc > 1 ? argv[1] : "000002.dat", "rb");

if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* read no. of int32_t values from 1st value in file */
if (fread (&nint, 1, sizeof nint, fp) != sizeof nint) {
perror ("fread-nint");
return 1;
}
...

现在只需使用 malloc() (推荐)为剩余值分配存储空间,或者您可以声明一个可变长度数组,但您应该检查变量的数量值以确保您不会尝试声明超出堆栈大小的数组 - 这将取决于编译器/操作系统。 MS 通常提供 1M 堆栈,因此您应该能够声明大约 200K 整数的 VLA——与您拥有的任何其他堆栈使用相平衡。使用 malloc 进行简单的动态分配将消除 StackOverflow 的风险...

    ...
/* allocate/validate storage */
if (!(a = malloc (nint * sizeof nint))) {
perror ("malloc-a");
return 1;
}
...

剩下的就是使用 fread 从文件中读取其余值。 fread 函数读取多个给定大小的 block ,并将结果存储在提供的地址中。因此,您只想读取 sizeof nintnint 值(或者您可以使用 sizeof *a - 两者都是相同的类型)。返回将是从文件中读取的该大小的 block 的数量。您可以通过以下方式读取剩余值:

    ...
/* read remaining values from file into a */
if (fread (a, sizeof nint, (size_t)nint, fp) != (size_t)nint) {
perror ("fread-a");
return 1;
}
fclose (fp); /* close file */
...

(注意:始终验证您的分配是否成功,并通过检查 fread 的返回来验证您从文件中的读取。)

确认从文件中读取的 32 位值的数量的完整示例可能是:

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

int main (int argc, char **argv) {

int32_t *a = NULL, nint = 0; /* pointer and no. of int */
/* use filename provided as 1st argument ("000002.dat" by default) */
FILE *fp = fopen (argc > 1 ? argv[1] : "000002.dat", "rb");

if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* read no. of int32_t values from 1st value in file */
if (fread (&nint, 1, sizeof nint, fp) != sizeof nint) {
perror ("fread-nint");
return 1;
}
/* allocate/validate storage */
if (!(a = malloc (nint * sizeof nint))) {
perror ("malloc-a");
return 1;
}
/* read remaining values from file into a */
if (fread (a, sizeof nint, (size_t)nint, fp) != (size_t)nint) {
perror ("fread-a");
return 1;
}
fclose (fp); /* close file */

/* report number of integers read */
printf ("%d int32_t read from file.\n", nint);
}

示例使用/输出

使用您提供的链接的文件,并将要读取的文件名作为程序的第一个参数传递(或默认从当前目录中的文件读取),您将得到:

$ ./bin/freadint32_t ../dat/000002.dat
892 int32_t read from file.

文件中的值

如果通过添加一个简单的循环来输出文件中的值,您会发现:

16  25  22  11  17  20  19  23  22  16
17 22 25 25 18 22 24 17 15 18
25 14 14 29 16 14 23 23 21 20
28 24 17 22 18 21 22 24 27 16
16 21 22 30 28 18 23 20 15 23
20 19 22 22 23 20 18 20 28 22
21 22 20 30 21 17 24 22 21 18
19 20 20 25 22 20 30 26 25 33
21 15 23 22 19 17 17 20 21 21
27 35 27 19 21 22 19 13 18 18
12 20 25 22 24 21 20 26 22 24
30 22 18 22 20 16 18 23 22 24
23 17 22 22 17 23 22 16 24 25
20 18 18 25 24 23 22 17 23 26
22 16 17 25 27 24 23 26 23 20
24 17 10 23 22 13 20 16 16 22
18 23 25 20 28 24 21 26 22 24
22 24 25 19 26 28 21 18 21 25
24 19 20 21 19 20 19 19 18 29
...
25 23 18 19 25 23 19 23 22 18
22 19 16 15 13 25 26 23 26 20
23 16 14 23 20 23 22 24 26 19
20 18

读取所有 892 个值。

仔细检查一下,如果您还有其他问题,请告诉我。

关于c - 使用 C 无法读取 4 字节整数 (Int32) 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com