c - fread 或 fwrite 给出 "Bad file number"

标签 c gcc fwrite fgets

我在 Windows 8.1 中使用 MinGW,我有一个原始数字的输入文本文件(每行一个),我想将它们作为二进制文件写入一个新的二进制文件中。该示例编译时没有问题:

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)

最佳答案

您的程序中有多个错误:

  • 您应该测试是否无法创建输出文件。

  • 您应该测试 fgets() 的返回值,而不是使用 while (!feof())...,它不会执行您想要的操作按照Why is “while ( !feof (file) )” always wrong?中的解释思考

  • 您应该将 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;
}

shell 诊断具有误导性,但它的含义如下:文件 my_code.exe 具有无法识别为可执行文件的签名(也称为魔数(Magic Number))。内核无法根据其魔数(Magic Number)确定如何运行该文件,因此错误的文件号

原因是您的编译命令: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

关于c - fread 或 fwrite 给出 "Bad file number",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39844276/

相关文章:

C - 使用 while 和 switch/case 的菜单程序返回具有无效选择的重复菜单

php - 如何获得需要上下文的字符串的复数翻译?

c - 为什么 scanf llu 不验证 %llu?

c++ - 退回 VLA 安全吗?

c++ - 编译> 2 GB的代码时如何修复GCC编译错误?

time_t 的 C 字符串表示

c++ - 我如何在 GCC 下强制 'bool' 的大小

c - fwrite 只写入第一个元素并删除所有后续元素

c - 文件返回垃圾,但写入正确

php - fclose 警告 : fclose(): supplied argument is not a valid stream resource