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

时间:2018-01-03 15:45:38

标签: c++ bmp fgetc

我目前正在尝试使用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

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

2 个答案:

答案 0 :(得分: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");

答案 1 :(得分:2)

更改

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

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

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