fread не запускается в начале файла - PullRequest
1 голос
/ 29 января 2020

Я работаю над проектом, который включает чтение двоичных данных из файла в определенные структуры данных. Во время тестирования я увидел, что в эти структуры загружаются неверные данные. Добавление небольшого кода отладки (с использованием ftell) показало, что fread начинается не с начала файла, а с некоторым смещением в сотни байт. Что может быть причиной этого?

Я пытался добавить fseek(infile, 0, SEEK_SET); перед первым fread вызовом, но первый вызов все еще начинался с тем же смещением, что и раньше. Я также пытался использовать rewind(infile) безрезультатно. Я видел, что возникла ли эта проблема, зависит от читаемого файла. Некоторые файлы всегда начинаются с позиции 0, в то время как другие всегда начинаются с другого смещения.

Вот минимальный пример кода, который демонстрирует эту проблему на моем компьютере. В настоящее время я использую Windows 10, и код был скомпилирован в Visual Studio.

#include <stdio.h>


int main(int argc, char* argv[]) {

    FILE* infile;
    char* inname;
    char x;

    inname = argv[1];

    if ( (fopen_s(&infile, inname, "r")) != 0) {
        printf("Error opening file: %s\n", inname);
        exit(1);
    }

    if (infile == 0) {
        printf("Error opening file.\n");
        exit(1);
    }


    while (fread(&x, sizeof(char), 1, infile) == 1) {
        printf("%ld\n", ftell(infile));
        printf("%hhx\n\n", x);
    }


    fclose(infile);

    return 0;
}

1 Ответ

3 голосов
/ 29 января 2020

Вы должны открыть файл в режиме двоичного чтения.

if ( (fopen_s(&infile, inname, "r")) != 0) {

до

if ( (fopen_s(&infile, inname, "rb")) != 0) {

От fopen man

Строка режима может также включать букву «b» либо в качестве последнего символа, либо в качестве символа между символами в любой из двухсимвольных строк, описанных выше. Это строго для совместимости с C89 и не имеет никакого эффекта; 'b' игнорируется во всех системах, соответствующих POSIX, включая Linux. ( Другие системы могут по-разному обрабатывать текстовые файлы и двоичные файлы, и добавление 'b' может быть хорошей идеей, если вы выполняете ввод-вывод в двоичный файл и ожидаете что ваша программа может быть перенесена в не UNIX среды .)

...