You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么while循环中fgets()、fread()无法正确替代scanf()?

问题原因及修复方案

故障根因

你原来的scanf("%s", kbinput)会自动跳过输入前的所有空白字符,且读到空白字符就停止,不会把末尾的换行符存入缓冲区,因此匹配"~"逻辑正常。换成fgets/fread后异常的原因如下:

  • fgets读取输入时会将输入末尾的**换行符\n**一同存入目标缓冲区,你输入~后按回车,实际存入kbinput的是"~\\n",和匹配串"~"不一致,strcmp返回非0,无法触发break。如果之前有scanf调用残留的换行符在stdin缓冲区,首次调用fgets还会直接读到空行,进一步导致匹配失败。
  • fread是面向二进制流的按块读取接口,不会自动在读取内容末尾加字符串结束符\0,后续调用strcmp、system这类要求合法C字符串的函数会触发内存越界,出现不可预期的异常,完全不适合读取键盘输入的字符串。

修复后的fgets实现代码

#include <string.h> // 需要引入头文件处理字符串

while (1){
    system("echo $PWD$");
    // 读取输入,读取失败(如遇到EOF)直接退出循环
    if (fgets(kbinput, 1000, stdin) == NULL) {
        break;
    }
    // 移除fgets读入的末尾换行符
    size_t input_len = strlen(kbinput);
    if (input_len > 0 && kbinput[input_len - 1] == '\n') {
        kbinput[input_len - 1] = '\0';
    }
    if (strcmp(kbinput,"~") == 0)
        break;
    fprintf(fptr,"%s\n",kbinput);
    system(kbinput);
}

注意事项

  • 要保证kbinput缓冲区的实际大小不小于fgets的第二个参数,避免缓冲区溢出。
  • 如果输入内容长度超过你设置的读取上限,fgets只会读满上限减1的内容,剩余数据会留在stdin缓冲区,下次调用fgets会继续读取,如有需要可以自行加逻辑清空缓冲区剩余内容。

内容的提问来源于stack exchange,提问作者user17267060

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 00:36:07