我正在尝试使用来自stdio.h的C库函数fputc
我假设它应该按照https://linux.die.net/man/3/fputc上的规范工作
具体来说,感兴趣的部分是:

  • fputc()将字符c(强制转换为无符号字符)写入流。
  • fputc(),putc()和putchar()将以无符号字符形式写入的字符转换为错误的int或EOF。

  • 基于此信息,我假设如果fputc成功将字符写入所提供的流,则我应该收到一个等于所写入字符的返回值,并且如果它未能写入流,则应该获得EOF的值。
    这是我的代码:
    // COMPILE
    //    gcc -Wall -Wextra -Werror -O3 -s ./fputc.c -o ./fputc-test
    // RUN
    //    ./fputc-test
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    
    void print_error_exit();
    
    int main() {
        FILE * fp;
    
        // ensure file exists
        if((fp = fopen("file", "w")) == NULL) print_error_exit();
    
        // close stream
        if(fclose(fp) == EOF) print_error_exit();
    
        // open file in read-only mode
        if((fp = fopen("file", "r")) == NULL) print_error_exit();
    
        // close stream
        if(fclose(fp) == EOF) print_error_exit();
    
        printf("EOF is: %d\n", EOF);
        // use fputc on a read-only closed stream (should return error, right?)
        printf("fputc returned: %d\n", fputc(97, fp)); // 97 is ascii for 'a'
        // expected:
        //    prints EOF (probably -1)
        // actual:
        //    prints 97 on linux with both gcc and clang (multiple versions tested)
        //    prints -1 on windows with mingw-gcc
    
        return EXIT_SUCCESS;
    }
    
    void print_error_exit() {
        fprintf(stderr, "%s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    
    我已经使用gcc 8.1.0,gcc 8.3.0,gcc 9.3.0和clang 7.0.1在Ubuntu 20,Debian 9,Windows 10上测试了代码。在Windows上,我使用过mingw。
    我发现的唯一趋势是fputc在Windows上返回了我期望的结果,而在Linux上没有返回我期望的结果。
    以下哪一项是正确的?
  • 我的代码中有一个错误(如果存在,请解释原因并发布固定代码)
  • 我对规范不正确(如果是,请更好地解释)
  • 为Linux编译时,gcc和clang中都存在错误(在哪里报告此问题?)
  • linux(某些发行版或全部发行版)存在错误(在哪里报告此错误?)

  • 请帮助我理解这一点。当我尝试在封闭的流(更不用说仅用于读取的流)上使用fputc时,为什么fputc不返回错误代码(EOF)?

    最佳答案

    您的代码表现出未定义的行为。
    J.2 Undefined behavior:


    关闭文件后,使用FILE对象无效,并且指针本身具有不确定的值。

    08-28 15:11