我试图一次读取C 1字节的二进制文件,并在搜索互联网几个小时后仍然无法检索除垃圾和/或seg故障之外的任何内容 . 基本上,二进制文件的格式为256项长度,每个项目为1个字节(0到255之间的无符号整数) . 我试图使用fseek和fread跳转到二进制文件中的“索引”并检索该值 . 我目前的代码:
unsigned int buffer;
int index = 3; // any index value
size_t indexOffset = 256 * index;
fseek(file, indexOffset, SEEK_SET);
fread(&buffer, 256, 1, file);
printf("%d\n", buffer);
现在这段代码给了我随机的垃圾数字和段错误 . 有关如何使其正常工作的任何提示?
5 回答
在您的代码中,您尝试将256个字节读取到一个int的地址 . 如果要一次读取一个字节,请调用
fread(&buffer, 1, 1, file);
(参见fread) .但更简单的解决方案是声明一个字节数组,一起读取并在此之后处理它 .
你的令人困惑的字节与int . 字节的常用术语是unsigned char . 大多数字节都是8位宽 . 如果您正在读取的数据是8位,则需要读取8位:
将所有数据读入存储器的原因是为了保持I / O流动 . 无论请求的数量如何,每个输入请求都会产生开销 . 一次读一个字节,或一次寻找一个位置是最坏的情况 .
以下是读取1个字节所需的开销示例:
在您的程序设计中,上述步骤将重复256次 . 根据每个人的建议,标有“ - >”的行将读取256个字节 . 因此,开销仅执行一次而不是256次以获得相同数量的数据 .
现在是时候阅读我相信的人 .
您正在尝试将256个字节读入一个名为“buffer”的4字节整数变量中 . 您正在覆盖其他252个字节的其他数据 .
似乎
buffer
应该是unsigned char buffer[256];
或者你应该做fread(&buffer, 1, 1, f)
,在这种情况下buffer
应该是unsigned char buffer;
.或者,如果你只想要一个字符,你可以将
buffer
保留为int
(不需要unsigned,因为C99保证了普通int的合理最小范围)并简单地说:几个问题与代码,因为它站立 .
fread的原型是:
您已将大小设置为256(字节)并将计数设置为1.这很好,这意味着“读取一个256字节的块,将其推入缓冲区” .
但是,您的缓冲区大约为2-8个字节(或者,至少远小于256个字节),因此您有一个缓冲区溢出 . 您可能想要使用fred(&buffer,1,1,file) .
此外,您正在将字节数据写入int指针 . 这将适用于一个endian-ness(实际上是小端),因此你可以在英特尔架构上做得很好,并从中学习坏习惯,这些日子会回来咬你 .
尝试很难将字节数据写入字节组织存储,而不是写入整数或浮点数 .