使用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
相关产品推荐
相关产品推荐

