C ++:麻烦阅读.BMP文件;文件结尾比预期更早到达

问题描述 投票:0回答:2

我目前正在尝试使用C ++读取.BMP文件,但不知何故,在读取了几个字节后,文件结束了(fgetc()返回-1)。我把问题简化为一个最小的例子:

#include <iostream>

int main()
{
    // Open file
    FILE* file = fopen("C:/Path/to/file", "r");

    // Get and print file size in bytes
    fseek(file, 0L, SEEK_END);
    std::cout << ftell(file) << std::endl;
    rewind(file);

    int byte, i = 0;
    do
    {
        // Get each byte
        byte = fgetc(file);
        // Print i and value of byte
        std::cout << i << ", " << byte << std::endl;
        i++;
    }
    // Stop reading when end of file is reached
    while (byte != EOF);

    std::cin.get();

    return 0;
}

当使用它来读取.BMP文件时(在.txt文件等简单格式上不会出现问题),它正确读取文件长度,但在到达文件末尾之前找到EOF方式。

例如,使用this file,它读取的文件长度为120054,但fgetc()在i = 253时返回-1

我究竟做错了什么,我该如何解决这个问题呢?

c++ bmp fgetc
2个回答
2
投票

更改

FILE* file = fopen("C:/Path/to/file", "r");

FILE* file = fopen("C:/Path/to/file", "rb");

以二进制模式读取文件。这通常有助于避免这种奇怪的错误。


3
投票

在DOS / Windows上以普通“r”模式读取文件可能会将ASCII 26(^ Z)视为“文件结束”。它也可以将行结尾从CR LF(13 10)转换为LF(10),这也是您不想要的。

看看你的示例文件,我确实看到了那个字符(它是十六进制的1A):

0000340 0c 1f 15 0e 1f 15 0e 1f 14 10 1f 14 10 21 17 10
0000360 21 17 10 22 18 11 23 19 12 25 19 13 26[1a]14 26

该位置为375八进制,即十进制253。听起来有点熟? :)

使用“rb”:

FILE* file = fopen("C:/Path/to/file", "rb");
© www.soinside.com 2019 - 2024. All rights reserved.