fprintf错误行为及特定C代码输出结果的技术问询
关于fprintf错误状态及给定C代码输出的解析
1. 若fprintf此前已触发错误,它会产生什么行为?原因是什么?
- 行为表现:如果目标文件流之前已经触发过错误(比如写入失败、文件意外关闭等),后续调用
fprintf会直接返回-1,不会执行任何实际的写入操作。 - 背后原因:C标准库的文件流会维护一个错误标志位(error indicator)。当某次I/O操作失败时,这个标志位会被置位。之后所有针对该流的I/O操作都会先检查这个标志位——只要它处于激活状态,操作就会直接失败返回,不会尝试执行任何实际的读写动作。要恢复流的正常使用,必须调用
clearerr()函数手动清除这个错误标志位。
2. 解析给定C代码的输出结果(仅输出"a"的原因)
先贴出代码方便分析:
#include <stdio.h> int main() { char c; int i = 0; FILE *file; file = fopen("test.txt", "w+"); fprintf(file, "%c", 'a'); fprintf(file, "%c", -1); fprintf(file, "%c", 'b'); fclose(file); file = fopen("test.txt", "r"); while ((c = fgetc(file)) != -1) printf("%c", c); return 0; }
写入阶段:三个字节其实都被写入了
首先要明确:代码里的三次fprintf都是成功执行的,文件test.txt里实际写入了三个字节:
- 第一个
fprintf写入字符'a'(ASCII值0x61) - 第二个
fprintf中,%c格式符会把传入的int类型-1转换为unsigned char类型,也就是0xFF(十进制255,属于不可打印的控制字符),这个字节被正常写入 - 第三个
fprintf写入字符'b'(ASCII值0x62)
读取阶段:变量类型导致循环提前终止
问题出在读取环节的变量定义和循环条件:
fgetc()函数的返回值是int类型:读取成功时返回对应字节的unsigned char转换为int(范围0~255);读取到文件末尾或出错时返回EOF(即-1)。- 但代码里把返回值赋值给了**
char类型的变量c。在绝大多数系统中,char默认是有符号类型**,这意味着0xFF这个字节被赋值给c时,会被解释为有符号数的-1。 - 当循环执行到读取
0xFF这个字节时,c的值变成了-1,此时循环条件(c = fgetc(file)) != -1就会判定为false,循环直接终止。后续的'b'字节根本没被读取到,所以最终只输出了'a'。
内容的提问来源于stack exchange,提问作者Golden Fish
相关产品推荐
相关产品推荐

