C语言登录注册程序问题:用户名输入环节被跳过直接进入密码输入
解决注册流程跳过用户名输入的问题
这个问题我太熟悉了——本质是输入缓冲区里残留的换行符在捣乱!让我给你拆解原因,再给出修复方案:
问题根源
你在main函数里用scanf("%d", &choice);获取用户的登录/注册选择,这个函数只会读取输入的数字,而你按下回车键时产生的换行符\n会留在输入缓冲区里。当signUp函数调用gets(username);时,gets会从缓冲区读取内容直到遇到换行符,它直接把这个残留的换行符当成了用户名的输入,所以看起来像是跳过了用户名步骤,直接进入密码输入环节。
另外额外提一句:gets是个不安全的函数,它不会检查输入长度,很容易导致缓冲区溢出,建议换成更安全的fgets。
修复方案
1. 清除输入缓冲区的残留换行符
在scanf读取完选择后,手动清除缓冲区里的换行符,用getchar()就可以搞定:
int choice; scanf("%d", &choice); // 吃掉scanf留下的换行符 getchar();
2. 替换gets为安全的fgets
用fgets替代gets,同时处理它会读取换行符的问题(用strcspn去掉字符串末尾的换行符):
修改signUp函数里的输入部分,同时把age改成指针传递(原来的传值方式不会修改main里的变量):
void signUp (char username [SIZE], char password [SIZE], char name [SIZE], int *age) { printf("Sign Up Procedure: \n"); printf("\nPlease enter your username: "); fgets(username, SIZE, stdin); // 去掉fgets读取的换行符 username[strcspn(username, "\n")] = '\0'; printf("\nPlease enter a password: "); fgets(password, SIZE, stdin); password[strcspn(password, "\n")] = '\0'; printf("\nEnter your full name: "); fgets(name, SIZE, stdin); name[strcspn(name, "\n")] = '\0'; printf("\nEnter your age: "); scanf("%d", age); printf("\nUsername: %s, Password: %s, Full Name: %s, Age: %d", username, password, name, *age); }
3. 修改main函数里的signUp调用
把原来的signUp (username, password, name, age);改成:
signUp (username, password, name, &age);
完整修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 需要包含这个头文件来使用strcspn #define SIZE 1000 void signUp (char username [SIZE], char password [SIZE], char name [SIZE], int *age) { printf("Sign Up Procedure: \n"); printf("\nPlease enter your username: "); fgets(username, SIZE, stdin); username[strcspn(username, "\n")] = '\0'; printf("\nPlease enter a password: "); fgets(password, SIZE, stdin); password[strcspn(password, "\n")] = '\0'; printf("\nEnter your full name: "); fgets(name, SIZE, stdin); name[strcspn(name, "\n")] = '\0'; printf("\nEnter your age: "); scanf("%d", age); printf("\nUsername: %s, Password: %s, Full Name: %s, Age: %d", username, password, name, *age); } void logIn(char username [SIZE], char password [SIZE]) { // 这里可以补充登录逻辑,比如读取保存的用户信息做对比 } int main() { printf("1. Log In\n"); // Enter 1 for logging in printf("2. Sign Up\n"); // Enter 2 for signing up int choice; scanf("%d", &choice); getchar(); // 清除缓冲区的换行符 char username [SIZE]; char password [SIZE]; char name [SIZE]; int age; int keepGoing = 0; while (keepGoing == 0){ switch (choice) { case 1: logIn (username, password); keepGoing = 1; break; case 2: signUp (username, password, name, &age); keepGoing = 1; break; default: printf("Please enter a choice from the given options\n"); // 重新获取选择,避免无限循环 scanf("%d", &choice); getchar(); break; } } FILE * pfile; pfile = fopen("Planner.txt", "w"); if (pfile != NULL) { // 检查文件是否成功打开 fputs("Planner", pfile); fclose(pfile); } else { printf("Failed to open file\n"); } return 0; }
这样修改后,注册流程就能正常读取用户名、密码等信息了,同时解决了gets的安全问题,还修复了age参数传递的小bug。
内容的提问来源于stack exchange,提问作者Kevin Kannammalil
相关产品推荐
相关产品推荐

