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

C语言for循环中使用fgets()遇过长输入导致循环异常的解决方法

问题分析

你的问题出在输入缓冲区残留的换行符和数组大小不匹配两个核心点上:

  1. 输入缓冲区残留字符:
    你给fgets的第二个参数是letter_count+1=5,这意味着fgets最多读取4个字符(因为最后要留一个位置存终止符\0)。当你输入foil\n(4个字符加换行)时,fgets只会把foil读进tempstring,换行符\n会留在标准输入缓冲区里。下一次循环时,fgets直接读取缓冲区里的\n,strcspn把这个换行符替换成\0,导致tempstring变成空字符串,所以会输出 found from 1。

  2. 数组越界风险:
    你的userStrings定义为char userStrings[4][4],每个子数组只能容纳3个有效字符加1个终止符\0。但你输入的foil是4个字符,用strcpy复制过去会直接越界,触发未定义行为,这是潜在的严重问题。

解决方案

步骤1:修正数组大小

把userStrings改成char userStrings[4][5],让每个元素能容纳4个有效字符加终止符,避免越界。

步骤2:清空输入缓冲区的残留字符

每次用fgets读取后,检查输入是否包含换行符:如果没有,说明输入的字符数超过了fgets的读取上限,需要把缓冲区里剩下的字符全部读完丢弃,避免影响下一次循环。

修正后的代码

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

int main() {
    int letter_count = 4;
    // 调整tempstring大小,留足空间存换行符+终止符
    char tempstring[letter_count + 2];
    // 每个元素能存4个字符+终止符
    char userStrings[4][letter_count + 1];
    
    for(int i = 0; i < 4; i++){
        fgets(tempstring, sizeof(tempstring), stdin);
        
        // 移除换行符
        tempstring[strcspn(tempstring, "\n")] = 0;
        
        // 检查是否有残留字符在缓冲区
        if (!strchr(tempstring, '\n')) {
            int c;
            // 读取直到换行符或EOF,清空缓冲区
            while ((c = getchar()) != '\n' && c != EOF);
        }
        
        strcpy(userStrings[i], tempstring);
        printf("\n%s found from %d\n", userStrings[i], i);
    }
    return 0;
}

补充说明

  • strchr(tempstring, '\n')用来判断fgets是否读到了换行符:如果没读到,说明输入的字符数超过了tempstring的长度,此时需要用getchar循环清空缓冲区。
  • 调整tempstring的大小为letter_count + 2,是为了能容纳最多letter_count个字符加换行符加终止符,确保strcspn能正确找到换行符(如果存在的话)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:42:18