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

使用for循环操作C语言结构体与数组时的输入异常问题求助

问题原因分析

你的代码出现输入异常的核心问题是混合使用gets()和scanf()时的缓冲区残留换行符,另外gets()本身是已被C标准废弃的不安全函数:

  • 用scanf()输入rollNo或sgpa后,按下的回车键会留下一个\n换行符在输入缓冲区中
  • 下一次循环调用gets()时,它会直接读取这个残留的\n作为输入,导致跳过名字的输入步骤
  • gets()不检查输入长度,一旦输入超过name数组的大小,会造成缓冲区溢出,引发未定义行为
修复方案

推荐使用更安全的fgets()读取字符串,并配合清理缓冲区的操作,以下是修复后的代码:

#include<stdio.h>
#include<string.h>
struct FYSD {
    char name[100];
    int rollNo;
    float sgpa;
};

int main()
{
    int i;
    struct FYSD student[5];
    int c; // 用于清理缓冲区的临时变量

    for(i = 0; i < 5; i++) {
        printf("Enter student name : ");
        // 用fgets读取字符串,限制读取长度避免溢出
        fgets(student[i].name, sizeof(student[i].name), stdin);
        // 去掉fgets读取到的末尾换行符
        student[i].name[strcspn(student[i].name, "\n")] = '\0';

        printf("Enter student roll no : ");
        scanf("%d",&student[i].rollNo);
        // 清理scanf后缓冲区残留的换行符
        while((c = getchar()) != '\n' && c != EOF);

        printf("Enter student sgpa : ");
        scanf("%f",&student[i].sgpa);
        // 再次清理缓冲区,避免影响下一轮循环
        while((c = getchar()) != '\n' && c != EOF);
    }

    // 可选:添加打印代码验证输入结果
    for(i = 0; i < 5; i++) {
        printf("\nStudent %d:\nName: %s\nRoll No: %d\nSGPA: %.2f\n", 
               i+1, student[i].name, student[i].rollNo, student[i].sgpa);
    }
    return 0;
}
关键修复点解释
  • 替换gets()为fgets():fgets()会限制读取的字符数,从根源避免缓冲区溢出风险,同时会读取输入末尾的换行符
  • 去除换行符:用strcspn()定位到换行符的位置,替换为字符串结束符\0,避免名字中残留换行符影响后续使用
  • 清理缓冲区:每次用scanf()读取数字后,用getchar()循环清空缓冲区中残留的换行符,确保下一轮的字符串读取不受干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:32:49