2025年最新C语言教程21-标准IO库避坑指南

一、字符输入:getchar()必须返回int类型

错误案例

char c;
while ((c = getchar()) != EOF) {  // 错误:c是char类型
    putchar(c);
}

错误原因

  • char为有符号类型:正常字符0xFF(ÿ)会被误判为EOF
  • char为无符号类型:EOF(-1)转为0xFF(255),循环永不终止

正确写法

int c;  // 必须用int存储
while ((c = getchar()) != EOF) {
    putchar(c);
}

原理
int类型可同时存储字符值(0~255)和EOF(-1),确保判断准确。


二、文件读取:避免feof导致最后一行重复

错误案例

while (!feof(infp)) {  // 错误判断
    fgets(buf, sizeof(buf), infp);
    fputs(buf, outfp);
}

错误原因
feof仅在读取失败后返回真。当文件末尾无换行符时:

  1. 首次fgets读取最后一行 → 输出
  2. 再次循环时fgets读取失败,但buf仍存有旧数据 → 重复输出

正确写法

while (fgets(buf, sizeof(buf), infp) != NULL) {  // 检查fgets返回值
    fputs(buf, outfp);
}

关键原则

  • 用输入函数返回值(如fgets != NULL)判断读取成功
  • feof仅用于读取失败后区分文件结束/错误:
    if (feof(infp)) printf("文件结束");
    else perror("错误");
    


三、混合IO:解决scanffgets的换行符残留

错误案例

scanf("%d", &num);       // 输入"123\n"后残留'\n'
fgets(buf, 100, stdin);  // 读到'\n',buf为空行

解决方案

  1. 清除残留字符
    scanf("%d", &num);
    int c;
    while ((c = getchar()) != '\n' && c != EOF);  // 清空缓冲区
    

  2. 完全用fgets+sscanf替代
    fgets(num_buf, 100, stdin);  // 读取整行
    sscanf(num_buf, "%d", &num);  // 解析数据
    
    fgets(str_buf, 100, stdin);   // 无残留问题
    strchr(str_buf, '\n')[0] = '\0';  // 移除换行符(可选)
    

优势
fgets+sscanf彻底避免换行符干扰,是文档推荐做法。


标准IO库核心避坑准则

  1. getchar()返回值必存int
  2. 禁止单独用feof判断文件结束 → 检查输入函数返回值
  3. 绝对不用gets → 用fgets(buf, size, stdin)替代
  4. scanf后清除残留while((c=getchar())!='\n'&&c!=EOF)
  5. 处理fgets的换行符strchr(buf, '\n')[0] = '\0'
  6. 二进制文件用"rb"/"wb"模式 → 避免换行符转换
  7. 检查所有IO函数返回值 → 包括fopen, fread, scanf
  8. 禁止fflush(stdin) → 清除输入流用while(getchar()...)

遵循这些准则可规避90%的标准IO陷阱。核心思想:明确函数行为边界(如EOF本质是状态码而非字符)、严格检查返回值保持IO操作一致性(避免混合使用不同抽象层的函数)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迎風吹頭髮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值