C语言使用fgets()存储用户输入时跳过首个输入项问题求助
问题根因
你遇到的输入跳过问题是C语言混合使用scanf和fgets的经典问题:
- 菜单选择时使用的
scanf("%d")只会读取输入的数字,用户输入完数字按下的换行符\n会残留在输入缓冲区 - 进入
getFisherman()后第一个执行的fgets遇到缓冲区里的换行符,会直接判定已经读完一行,所以直接跳过SSN输入环节,继续执行后续代码。
解决方法
在调用fgets读取SSN之前,先清空输入缓冲区里残留的换行符即可,你可以在getFisherman()函数开头、读取SSN的代码前添加如下逻辑:
// 清空输入缓冲区残留的换行符 int c; while ((c = getchar()) != '\n' && c != EOF);
也可以统一所有输入都用fgets读取,再做对应类型转换,从根源上避免混合输入方法导致的问题。
其他代码优化建议
- 类型定义不规范:你定义结构体时的
typedef写法不符合标准C语法,建议改为标准写法,同时SSN、手机号这类不需要做数值计算的标识不需要存为int数组,存为字符串更合理:
你当前把SSN、手机号定义为int数组,用typedef struct Fisherman { char ssn[11]; // 10位数字加字符串结束符'\0',刚好11位 char fName[100]; char lName[100]; char phoneNo[12]; // 手机号同理存为字符串 char email[100]; } Fisherman;fgets读取字符串写入int数组会出现类型不匹配的内存错误,后续读写都会出现异常。 - 变量重名冲突:你全局定义了
Fisherman F1,main函数里又定义了Fisherman F1[100],重名会导致逻辑混乱,建议修改重复命名。 - 注册数据没有持久化:
getFisherman()里读取的所有内容都存在函数内的局部变量中,函数执行完就会销毁,注册的信息根本没有保存下来,建议把结构体数组或者指向结构体数组的指针作为参数传给getFisherman(),读取完直接存入结构体。 - 函数参数不规范:
mainMenu(MOption)、FishermanMenu(FManOption)没有指定参数类型,标准C要求必须明确参数类型,这两个函数实际不需要传参,直接删掉括号内的参数即可。 - 递归调用风险:
getFisherman()里如果用户选择1继续注册,会递归调用自身,如果连续注册次数过多会有栈溢出风险,建议改成循环实现重复注册的逻辑。 - 内存泄漏问题:main函数里用
malloc申请了pFisherman的内存,程序退出前没有用free释放,会出现内存泄漏。 - 非标准头文件引用:
<mem.h>不是标准C头文件,你已经引入了<string.h>就足够满足内存操作函数的使用需求,建议删掉<mem.h>避免跨编译环境报错。
内容的提问来源于stack exchange,提问作者tlbiro
相关产品推荐
相关产品推荐

