gpt4 book ai didi

c - fread() 的意外返回值

转载 作者:太空狗 更新时间:2023-10-29 17:15:14 25 4
gpt4 key购买 nike

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

int main()
{
FILE* bmp = NULL;
uint32_t offset;
uint8_t* temp = NULL;
size_t read;
unsigned int x_dim = 600, y_dim = 388;

bmp = fopen("test_colour.bmp", "r");

if (!bmp)
return -1;

/* Get the image data offset */
fseek(bmp, 10, SEEK_SET);
fgets((char*)&offset, 4, bmp);

printf("Offset = %u\n", offset);

temp = malloc(3*x_dim*y_dim*sizeof(uint8_t));

if (!temp)
return -1;

/* Go the the position where the image data is stored */
fseek(bmp, offset, SEEK_SET);

/* Copy image data to array */
printf("%u bytes requested!\n", 3*x_dim*y_dim);
read = fread((void*)temp, sizeof(uint8_t), 3*x_dim*y_dim, bmp);
printf("%Iu bytes read!\n", read);

fclose(bmp);
free(temp);

return 0;
}

我正在使用上面的代码将每像素 24 位 BMP 图像的 RGB 数据读取到数组中。根据 BMP 规范,图像数据从文件开头开始的偏移量(在 BMP header 之后)在偏移量 10 处给出。执行上述代码时得到以下输出。

Offset = 54
698400 bytes requested!
33018 bytes read!

偏移量输出似乎是正确的,因为文件大小为 698454 字节 (=698400+54)。但是,fread() 返回的值似乎表明无法读取整个图像数据。但是,我随后使用 temp 数组中的数据将 RGB 数据转换为灰度,并将此数据再次写入 BMP 文件。目视检查输出图像并没有指示任何错误,即似乎我实际上首先读取了整个输入图像,尽管 fread() 似乎指示不同。

有人可以解释这种行为吗?

最佳答案

(我敢打赌你在 Windows 上)

bmp = fopen("test_colour.bmp", "r");

应该是

bmp = fopen("test_colour.bmp", "rb");

如果文件在 Windows 上以文本模式打开,运行时将在碰巧遇到 0x1a (Ctrl-Z) 字节时停止读取,Windows 将其视为文本文件的 EOF 标记。即使它没有按 Ctrl-Z,当 Windows 将 CR/LF 序列转换为单个 LF 字符时,您也会得到损坏的数据。

但是,我无法解释为什么您能够从读取的部分文件中获得良好的图像(只是运气好?)。

您能够从缓冲区渲染图像,因为 fread() 实现确实读取了您请求的字节数(或几乎如此 - 该数字被四舍五入为某个 block 的倍数size) 放入缓冲区,然后它扫描缓冲区以查找要转换的 CR/LF 序列和 Ctrl-Z EOF 标志。

因此即使 fread() 返回 33018,缓冲区实际上已经几乎完全被文件中的数据写入。数据不是 100% 正确(例如,一些 CR 字符可能被丢弃)或完整,但在这种情况下它足够接近以呈现看起来像您预期的图像。

当然,这只是对这个特定运行时当前行为方式的观察——它在未来可能并不总是这样(甚至在今天的所有系统上)。

关于c - fread() 的意外返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11717120/

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