将用户名和密码保存到文件时未写入用户名
Username not written when saving username and password to a file
以下函数用于登录系统。除了变量“用户名”(用户输入)写入 nothing/blank(数据丢失),它 100% 工作,而变量“密码”完美写入数据。
void login()
{
while (1)
{
printf("Enter a selection (number 1 or 2), then press enter.\n\n");
printf("1. Login\n2. Register\n\n");
int selection = 0;
scanf("%d", &selection);
if (selection == 1)
{
FILE *fp;
char username[24] = {'[=10=]'};
printf("\nEnter username:\n");
fgets(username, sizeof(username), stdin);
int c = 0;
while ((c = getchar()) != '\n' && c != EOF);
char password[24] = {'[=10=]'};
printf("\nEnter password:\n");
fgets(password, sizeof(password), stdin);
char extension[4] = ".txt";
char fileName[strlen(username) + strlen(extension) + 1];
strcpy(fileName, username);
strcat(fileName, extension);
fp = fopen(fileName, "r");
if (fp != NULL)
{
char fileContents1[24] = {'[=10=]'};
char fileContents2[24] = {'[=10=]'};
for (int i = 0; i <= 1; i++)
{
if (i == 0)
{
fgets(fileContents1, sizeof(fileContents1), fp);
if (i == 1)
{
fgets(fileContents2, sizeof(fileContents2), fp);
}
}
if ((username == fileContents1) && (password == fileContents2))
{
menu();
} else
{
printf("\nInvalid username or password, try again.\n\n");
continue;
}
}
} else
{
printf("\nError, try again.\n\n");
continue;
}
fclose(fp);
} else if (selection == 2)
{
FILE *fp;
char username[24] = {'[=10=]'};
printf("\nChoose a username:\n");
fgets(username, sizeof(username), stdin);
int c = 0;
while ((c = getchar()) != '\n' && c != EOF);
char password[24] = {'[=10=]'};
printf("\nChoose a password:\n");
fgets(password, sizeof(password), stdin);
char extension[4] = ".txt";
char fileName[strlen(username) + strlen(extension) + 1];
strcpy(fileName, username);
strcat(fileName, extension);
fp = fopen(fileName, "w");
if (fp != NULL)
{
fputs(username, fp);
fputs(password, fp);
printf("\nLogin created successfully.\n\n");
} else
{
printf("\nError, try again.\n\n");
continue;
}
fclose(fp);
} else
{
printf("\nInvalid selection, try again.\n\n");
continue;
}
}
}
至少这些问题:
剩余 '\n'
scanf("%d", &selection);
不消耗数字后的任何内容,例如尾随的 '\n'
.
fgets()
读作 '\n'
- 非常短的一行。
scanf("%d", &selection);
...
fgets(username, sizeof(username), stdin);
最好不要将 scanf()
与 fgets(...,..., stdin)
混合使用。
最好只使用 fgets()
。
记住fgets()
读取并保存最后的'\n'
您可能想在 fgets()
之后砍掉潜在的 '\n'
。
username[strcspn(username, "\n")] = '[=11=]';
指针比较
username == fileContents1
比较2个字符串的地址。要比较字符串的 content,请使用 strcmp()
.
可疑代码
int c = 0; while ((c = getchar()) != '\n' && c != EOF);
在 fgets()
之后只有在 fgets()
未能读取整个 行 时才有意义。如果 fgets()
做了,那么这个 while()
读取并抛出下一行。
以下函数用于登录系统。除了变量“用户名”(用户输入)写入 nothing/blank(数据丢失),它 100% 工作,而变量“密码”完美写入数据。
void login()
{
while (1)
{
printf("Enter a selection (number 1 or 2), then press enter.\n\n");
printf("1. Login\n2. Register\n\n");
int selection = 0;
scanf("%d", &selection);
if (selection == 1)
{
FILE *fp;
char username[24] = {'[=10=]'};
printf("\nEnter username:\n");
fgets(username, sizeof(username), stdin);
int c = 0;
while ((c = getchar()) != '\n' && c != EOF);
char password[24] = {'[=10=]'};
printf("\nEnter password:\n");
fgets(password, sizeof(password), stdin);
char extension[4] = ".txt";
char fileName[strlen(username) + strlen(extension) + 1];
strcpy(fileName, username);
strcat(fileName, extension);
fp = fopen(fileName, "r");
if (fp != NULL)
{
char fileContents1[24] = {'[=10=]'};
char fileContents2[24] = {'[=10=]'};
for (int i = 0; i <= 1; i++)
{
if (i == 0)
{
fgets(fileContents1, sizeof(fileContents1), fp);
if (i == 1)
{
fgets(fileContents2, sizeof(fileContents2), fp);
}
}
if ((username == fileContents1) && (password == fileContents2))
{
menu();
} else
{
printf("\nInvalid username or password, try again.\n\n");
continue;
}
}
} else
{
printf("\nError, try again.\n\n");
continue;
}
fclose(fp);
} else if (selection == 2)
{
FILE *fp;
char username[24] = {'[=10=]'};
printf("\nChoose a username:\n");
fgets(username, sizeof(username), stdin);
int c = 0;
while ((c = getchar()) != '\n' && c != EOF);
char password[24] = {'[=10=]'};
printf("\nChoose a password:\n");
fgets(password, sizeof(password), stdin);
char extension[4] = ".txt";
char fileName[strlen(username) + strlen(extension) + 1];
strcpy(fileName, username);
strcat(fileName, extension);
fp = fopen(fileName, "w");
if (fp != NULL)
{
fputs(username, fp);
fputs(password, fp);
printf("\nLogin created successfully.\n\n");
} else
{
printf("\nError, try again.\n\n");
continue;
}
fclose(fp);
} else
{
printf("\nInvalid selection, try again.\n\n");
continue;
}
}
}
至少这些问题:
剩余 '\n'
scanf("%d", &selection);
不消耗数字后的任何内容,例如尾随的 '\n'
.
fgets()
读作 '\n'
- 非常短的一行。
scanf("%d", &selection);
...
fgets(username, sizeof(username), stdin);
最好不要将 scanf()
与 fgets(...,..., stdin)
混合使用。
最好只使用 fgets()
。
记住fgets()
读取并保存最后的'\n'
您可能想在 fgets()
之后砍掉潜在的 '\n'
。
username[strcspn(username, "\n")] = '[=11=]';
指针比较
username == fileContents1
比较2个字符串的地址。要比较字符串的 content,请使用 strcmp()
.
可疑代码
int c = 0; while ((c = getchar()) != '\n' && c != EOF);
在 fgets()
之后只有在 fgets()
未能读取整个 行 时才有意义。如果 fgets()
做了,那么这个 while()
读取并抛出下一行。