fread или fwrite дают "Плохой номер файла"

Я использую MinGW в Windows 8.1, и у меня есть входной текстовый файл необработанных чисел (по одному на строку), и я хочу записать их как двоичный файл в новый двоичный файл. Пример компилируется без проблем с:

gcc -pedantic -Os -c my_code.c -o my_code.exe

но выход

$ my_code.exe
sh: ./my_code.exe: Bad file number

Это код, который я написал:

#include<stdio.h>

int main ()
{
    FILE *fp;
    FILE *prob;
    int length;
    char buffer[30];

   // Open file containing numbers
    if ((prob = fopen("raw_numbers.txt","r")) == NULL)
    {
        printf("Could not open raw_numbers.txt\n");
        exit(1);
    }

    /* Create output binary file */
    fp = fopen( "file.bin" , "w" );

    while( ! feof(prob) )
    {
        fgets(buffer, sizeof(buffer), prob);
        fwrite((const void*) & buffer, 1, sizeof(buffer), fp);
    }

    fclose(prob);
    fclose(fp);
    return(0);
}

С помощью

$ gcc --version
gcc (GCC) 3.4.4 (msys special)

1 ответ

Решение

У вас есть несколько ошибок в вашей программе:

  • Вы должны проверить, не удалось ли создать выходной файл.

  • вы должны проверить возвращаемое значение fgets() Вместо того, чтобы использовать while (!feof())..., который не делает то, что вы думаете, как описано в разделе Почему "while (!feof (file))" всегда неверно?

  • ты должен пройти buffer в fwrite вместо &buffer

  • Вы должны передать количество байтов для записи (strlen(buffer)) вместо размера буфера.

  • вы говорите, что выходной файл должен быть двоичным, но вы открываете его как текстовый файл и записываете в него текст. Вы хотели преобразовать числа в двоичное и записать двоичное представление?

Вот альтернатива, которая реализует вышеупомянутое:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *fp;
    FILE *prob;
    int value;
    char buffer[30];

    /* Open file containing numbers */
    if ((prob = fopen("raw_numbers.txt", "r")) == NULL) {
        printf("Could not open raw_numbers.txt: %s\n", strerror(errno));
        exit(1);
    }

    /* Create output binary file */
    if ((fp = fopen("file.bin", "wb")) == NULL) {
        printf("Could not open file.bin: %s\n", strerror(errno));
        exit(1);
    }

    while (fgets(buffer, sizeof(buffer), prob) != NULL) {
        value = atoi(buffer);
        if (fwrite(&value, sizeof(value), 1, fp) != 1) {
            printf("Error writing to file.bin: %s\n", strerror(errno));
            exit(1);
        }
    }

    fclose(prob);
    fclose(fp);
    return 0;
}

Диагностика оболочки вводит в заблуждение, но вот что она означает: файл my_code.exe имеет подпись (также известную как магическое число), которая не распознается как исполняемый файл. Ядро не может определить, как запустить файл по его магическому номеру, отсюда и неправильный номер файла.

Причина в вашей команде компиляции: gcc -pedantic -Os -c my_code.c -o my_code.exe компилирует исходный файл my_code.c в объектный формат вместо прямой ссылки на исполняемый формат. Удалить -c Вариант для компиляции и ссылки в один шаг:

gcc -pedantic -Os my_code.c -o my_code.exe
Другие вопросы по тегам