В настоящее время я пытаюсь читать файлы .BMP, используя C ++, но каким-то образом после чтения нескольких байтов достигается конец файла (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 до достижения конца файла.
Например, используя этот файл, он читает файл длиной 120054, но fgetc()
возвращается -1
при i = 253.
Что именно я делаю не так, и как я могу решить эту проблему?
+ Изменить
FILE* file = fopen("C:/Path/to/file", "r");
в
FILE* file = fopen("C:/Path/to/file", "rb");
прочитать файл в двоичном режиме. Это обычно помогает избежать таких странных ошибок.
Чтение файла в обычном режиме «r» в DOS / Windows может рассматривать 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");