Расширение правильного ответа от SigTerm , вот некоторый фон , почему вы получили эффект от открытия файла PNG в текстовом режиме:
Формат PNG объясняет свой 8-байтовый заголовок файла следующим образом:
Первые восемь байтов файла PNG всегда содержат следующие значения:
(decimal) 137 80 78 71 13 10 26 10
(hexadecimal) 89 50 4e 47 0d 0a 1a 0a
(ASCII C notation) \211 P N G \r \n \032 \n
Эта подпись идентифицирует файл как файл PNG и обеспечивает немедленное обнаружение распространенных проблем с передачей файлов. Первые два байта различают файлы PNG в системах, которые ожидают, что первые два байта будут однозначно идентифицировать тип файла. Первый байт выбирается как не-ASCII-значение, чтобы уменьшить вероятность того, что текстовый файл может быть неправильно распознан как файл PNG; Кроме того, он перехватывает неверные передачи файлов, которые сбрасывают бит 7. Байты со второго по четвертый называют формат. Последовательность CR-LF ловит неверные передачи файлов, которые изменяют последовательности новой строки. Символ control-Z останавливает отображение файла под MS-DOS. Последний перевод строки проверяет наличие обратной задачи перевода CR-LF.
Я полагаю, что в текстовом режиме вызов fread()
был прерван, когда он прочитал шестой байт, содержащий символ Ctrl + Z. Ctrl + Z исторически использовался в MSDOS (и в CPM до него) для указания конца файла, что было необходимо, поскольку файловая система сохраняла размер файла в виде количества блоков, а не количества байтов.
Считывая файл в текстовом режиме вместо двоичного, вы включили защиту от случайного использования команды TYPE
для отображения файла PNG.
Единственное, что вы могли бы сделать, чтобы помочь диагностировать эту ошибку, это использовать fread()
немного по-другому. Вы не проверяли возвращаемое значение из fread()
. Вам следует. Далее, вы должны назвать это так:
...
size_t nread;
...
nread = fread(buffer, sizeof(buffer), 1, f);
, так что nread
- это число байтов, фактически записанных в буфер. Для файла PNG в текстовом режиме он сказал бы вам при первом чтении, что он читает только 5 байтов. Поскольку файл не может быть таким маленьким, вы бы знали, что происходит что-то еще. Оставшиеся байты буфера никогда не изменялись с помощью fread()
, что было бы замечено, если бы вы инициализировали буфер каким-либо другим значением заполнения.