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

使用fgets输入字符串时strchr字符查找异常,改用gets则正常

搞定你的fgets/strchr问题!

嘿,我来帮你理清这个问题——你用fgets替换gets后程序不正常,核心是这两个函数的行为差异,再加上输入缓冲区的小坑在捣乱:

1. fgets会把换行符也读进字符串里

gets读取输入时,会自动把你按下回车的换行符(\n)丢掉;但fgets会把这个换行符一并存到你的input数组里。这直接导致两个问题:

  • 你的目标字符串末尾多了个隐形的\n
  • 当你用getchar()读要找的字符时,实际上读到的是输入字符串后剩下的换行符,根本不是你后来输入的那个字符!

2. fgets的长度参数设小了

你代码里写的fgets(input, 16, stdin),意味着最多读15个有效字符(最后一位要留个\0当终止符)。如果用户输入超过15个字符,剩下的字符会留在输入缓冲区里,同样会干扰后续的getchar()操作。


修复后的完整代码

下面是修正后的版本,把坑都填上了:

#include <stdio.h>
#include <string.h>

int main() {
    char let;
    char input[50];
    char *ptr;

    printf("what is the string that you would like to check?\n");
    // 用fgets读取,然后去掉末尾的换行符
    if (fgets(input, sizeof(input), stdin) != NULL) {
        // strcspn会返回第一个换行符的位置,直接替换成终止符
        input[strcspn(input, "\n")] = '\0';
    }

    printf("what is the character that you would like to find?\n");
    // 先跳过输入缓冲区里残留的换行符,确保读到的是用户输入的目标字符
    while ((let = getchar()) == '\n') {
        // 啥也不用做,就是跳过换行
    }

    printf("in string \"%s\"...\n", input);
    ptr = strchr(input, let);
    while (ptr != NULL) {
        printf("the character %c was found at character %d\n", let, ptr - input + 1);
        ptr = strchr(ptr + 1, let);
    }

    return 0;
}

关键修复细节:

  • 用strcspn快速定位换行符并替换成\0,去掉字符串尾巴上的换行
  • 在getchar()前加了个循环,把缓冲区里剩的换行符都跳过,保证读到的是你真正要找的字符
  • 把fgets的长度改成sizeof(input),充分利用数组的50个位置,避免输入被截断

额外提醒

  • 绝对不要再用gets了:这货没有边界检查,很容易造成缓冲区溢出,早就被C标准废弃了,属于高危函数
  • 处理控制台输入时,一定要注意输入缓冲区里的残留字符,很多奇怪的输入问题都是因为这个

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:53:15