Запись и чтение бинарного файла в c

Я пытаюсь записать целое число в двоичный файл, а затем прочитать то же самое. Однако моя программа читает не тот номер, который был написан. Что я делаю не так?

unsigned short int numToWrite = 2079;
    // Write to output
    FILE *write_ptr;
    write_ptr = fopen("test.bin","wb");  // w for write, b for binary
    printf("numToWrite: %d\n", *(&numToWrite));
    fwrite(&numToWrite, sizeof(unsigned short int), 1, write_ptr); // write 10 bytes from our buffer
    fclose(write_ptr);

    // Read the binary file
    FILE *read_ptr = fopen(filename, "rb");
    if (!read_ptr) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    unsigned short int* numToRead = malloc(sizeof (unsigned short int));
    fread(numToRead, sizeof(unsigned short int), 1, read_ptr);
    printf("numToRead: %d\n", *numToRead);
    free(numToRead);
    fclose(read_ptr);

Вывод таков:

numToWrite: 2079
numToRead: 26964

person Ali Moosavi    schedule 04.04.2021    source источник
comment
Это не компилируется, потому что filename не определено. Также есть несколько недекларированных функций. Пожалуйста, приведите полный пример.   -  person Ture Pålsson    schedule 04.04.2021
comment
Предоставьте минимально воспроизводимый пример.   -  person Andreas Wenzel    schedule 04.04.2021
comment
Если вы используете numToWrite, то, когда вы используете numToRead, вы должны снова использовать только короткий int, а не короткий int * ДЛЯ ЯСНОСТИ. Таким образом, вы также можете избежать использования malloc   -  person George Kourtis    schedule 05.04.2021


Ответы (2)


man printf

Модификатор длины

h - следующее целочисленное преобразование соответствует короткому или беззнаковому короткому аргументу, ...

Спецификаторы конверсии

d,i - Аргумент int преобразуется в десятичную запись со знаком.

Формат строки формата

...
Каждая спецификация преобразования начинается с символа % и заканчивается спецификатором преобразования. Между ними может быть (в этом порядке) ноль или более флагов, необязательная минимальная ширина поля, необязательная точность и необязательный модификатор длины.

Вы используете unsigned short int, но это не то, что вы говорите printf. Следовательно, ваши ожидания не оправдались.

person Erdal Küçük    schedule 04.04.2021

Несколько вещей, которые происходят:

'printf' не имеет спецификатора двоичного формата, поэтому вам придется делать это вручную.

Вам необходимо глубоко изучить типы данных и их диапазоны, поэтому я рекомендую использовать этот источник: Диапазоны типов данных Microsoft. Там написано C++, это не имеет значения, поскольку дает хорошее представление о диапазонах.

Я знаю, что это не весь ваш код, но просто поймите, что из того, что я вижу, есть что-то, что не определено, например, «имя файла».

Если кто-то упоминает atoi() и itoa(), имейте это в виду, теоретически вы можете использовать atoi() и itoa(), однако просто помните, что atoi() и itoa() - это нестандартные функции, которые поддерживаются некоторыми компиляторами.

Наконец, почему вы используете «unsigned short int», «*(&numToWrite)» и есть ли что-то еще из программы, которую вы можете нам показать?

person untraditionalprogrammer    schedule 04.04.2021