我正在尝试使用来自stdio.h的C库函数fputc
我假设它应该按照https://linux.die.net/man/3/fputc上的规范工作
具体来说,感兴趣的部分是:
基于此信息,我假设如果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上没有返回我期望的结果。
以下哪一项是正确的?
请帮助我理解这一点。当我尝试在封闭的流(更不用说仅用于读取的流)上使用fputc时,为什么fputc不返回错误代码(EOF)?
最佳答案
您的代码表现出未定义的行为。
从J.2 Undefined behavior:
关闭文件后,使用FILE
对象无效,并且指针本身具有不确定的值。