C语言驾驶员信息录入程序中结构体成员输入被跳过问题求助
问题分析与解决方案
问题根源
- 输入缓冲区残留换行符:使用
scanf("%d", &n)读取驾驶员数量后,输入时按下的回车键会在缓冲区留下一个\n换行符。而gets()函数会直接读取这个换行符作为空输入,导致第一个姓名输入被跳过。 gets()函数不安全:该函数不检查输入长度,若输入内容超过数组容量会引发缓冲区溢出,且已被C11标准废弃。
修复步骤
1. 清除scanf后的残留换行符
在scanf("%d", &n);之后添加代码,吃掉缓冲区里的换行符:
getchar(); // 读取并丢弃换行符
2. 替换gets()为安全的fgets()
fgets()会读取指定长度的字符,但会保留输入末尾的换行符,因此需要手动截断换行符,可借助strcspn()函数实现:
// 读取姓名并去除换行符 fgets(arr[i].name, sizeof(arr[i].name), stdin); arr[i].name[strcspn(arr[i].name, "\n")] = '\0';
3. 优化数据类型(可选)
行驶里程是数值,建议用int类型存储而非字符数组,方便后续计算或格式化输出。
修改后的完整代码
#include <stdio.h> #include <string.h> // 用于strcspn函数 struct driver_details { char name[50]; char licence_no[25]; char route[20]; int kms; // 改为int类型存储里程 }; void displayDetails(struct driver_details arr) { printf("\t1. Name of the driver: %s\n", arr.name); printf("\t2. Driving License Number: %s\n", arr.licence_no); printf("\t3. Route followed: %s\n", arr.route); printf("\t4. Total Kilometers travelled: %d\n", arr.kms); // 对应int类型输出 } int main() { int n; printf("Enter the number of drivers:\n"); scanf("%d", &n); getchar(); // 清除scanf残留的换行符 struct driver_details arr[n]; for (int i = 0; i < n; ++i) { printf("Enter the detail of driver number: %d\n", (i + 1)); printf("Enter your name:\n"); fgets(arr[i].name, sizeof(arr[i].name), stdin); arr[i].name[strcspn(arr[i].name, "\n")] = '\0'; // 去除换行符 printf("Enter your driving license number:\n"); fgets(arr[i].licence_no, sizeof(arr[i].licence_no), stdin); arr[i].licence_no[strcspn(arr[i].licence_no, "\n")] = '\0'; printf("Enter your route:\n"); fgets(arr[i].route, sizeof(arr[i].route), stdin); arr[i].route[strcspn(arr[i].route, "\n")] = '\0'; printf("Enter the kilometers travelled:\n"); scanf("%d", &arr[i].kms); getchar(); // 清除scanf读取里程后的换行符 printf("\n"); } for (int i = 0; i < n; ++i) { printf("The details of the driver %s:\n", arr[i].name); displayDetails(arr[i]); } return 0; }
代码说明
strcspn(arr[i].name, "\n")会返回字符串中第一个换行符的位置,将该位置设为\0就能截断换行符。- 读取里程用
scanf("%d", &arr[i].kms)后,同样需要用getchar()清除残留的换行符,避免影响下一轮循环的fgets()输入。 - 可变长度数组
struct driver_details arr[n]在C99及以后标准支持,若编译器不支持,可改用动态内存分配(malloc)。
内容的提问来源于stack exchange,提问作者Snigdha Pandey
相关产品推荐
相关产品推荐

