在 C 中使用 Do.while 循环登录



我需要制作一个程序,要求输入用户名和密码,如果它们都正确,请继续菜单。 由于某种原因,当前输入正确的用户名和错误的密码仍然会提示我进入菜单,但是如果我输入错误的用户名和正确的密码,它不会.此外,如果我从第一次尝试中输入正确的用户名和密码,它总是返回"错误的用户名或密码重试"。这是代码:

#include <stdio.h>
#include <string.h>
#define user "kaiti"
#define pass "123Pass!"        
int main()
{
char username[20], password[20];
//-----LOGIN PHASE-----
printf("Please Enter username:");
scanf("%s", &username);
printf("nPlease enter password:");
scanf("%s", &password);
do
{
printf("Wrong username or password try again!n");
printf("nPlease Enter username:");
scanf("%s", &username);
printf("nPlease enter password:");
scanf("%s", &password);
}
while (strcmp(username, user) != 0 && strcmp(password, pass) != 0);
printf("Correct username and password.nnWelcome Mrs.Kaiti!nnWhat would you like to do?");
//-----END OF LOGIN PHASE-----

你的布尔表达式是错误的。有效大小写为strcmp(username, user) == 0 && strcmp(password, pass) == 0(用户名和密码正确)。它的反转是strcmp(username, user) != 0 || strcmp(password, pass) != 0(意味着"其中一个条件不满足")。

对于关于在第一轮不显示通知的第二个问题,您可以使用如下所示的简单增量(i必须初始化为0):

if (i++ > 0) {
printf("Wrong username or password try again!n");
}

do-while 循环以消息开头

printf("Wrong username or password try again!n");

因此,您始终会在程序中收到此消息,具体取决于用户输入的内容。

本声明和类似声明

scanf("%s", &username);
^^^

至少应该写成

scanf("%s", username);
^^^ 

尽管在任何情况下此语句都是不安全的,因为用户可以覆盖输入字符数组。

相反,最好使用标准函数fgets

循环的这个条件

while (strcmp(username, user) != 0 && strcmp(password, pass) != 0);
^^

错了,应该有

while (strcmp(username, user) != 0 || strcmp(password, pass) != 0);
^^

该程序可以如下所示

#include <stdio.h>
#include <string.h>
#define USER    "kaiti"
#define PASS    "123Pass!"        
#define N   20
int main(void) 
{
char username[N], password[N];
int valid = 0;
do
{
size_t n, m;
//-----LOGIN PHASE-----
printf( "Please Enter username (no more than %u symbols): ", N - 2 );
fgets( username, N, stdin );
printf("nPlease enter password (no more than %u symbols): ", N - 2 );
fgets( password, N, stdin );

n = strcspn( username, "n" );
m = strcspn( password, "n" );
valid = username[n] == 'n' && password[m] == 'n';
username[n] = '';
password[m] = '';
valid = valid && strcmp( username, USER ) == 0 && strcmp( password, PASS ) == 0;
if ( !valid )
{
printf("nWrong username or password try again!nn");
}
} while ( !valid );
printf("Correct username and password.nnWelcome Mrs.Kaiti!nnWhat would you like to do?");
//-----END OF LOGIN PHASE-----  return 0;
}

它的输出可能看起来像

Please Enter username (no more than 18 symbols): kaiti
Please enter password (no more than 18 symbols): 123Pass
Wrong username or password try again!
Please Enter username (no more than 18 symbols): kaiti
Please enter password (no more than 18 symbols): 123Pass!
Correct username and password.
Welcome Mrs.Kaiti!
What would you like to do?

在第一次尝试中,用户输入了错误的密码。

您还可以限制用户为循环引入计数器的尝试次数。

你想要一个while (condition) { /* body */ }循环。

不要在scanf调用中使用数组的地址:scanf("%s", username);。数组将自动转换为指向其第一个元素的指针。

  • 如果您使用 do-while-loop,它将始终在检查 while 条件之前运行循环。因此,在循环之前插入什么并不重要,因为它总是会在第一次运行时跳入循环。你可以通过使用while循环来解决它,或者把所有东西都放在do-while循环中,稍微改变一下
  • while 循环中的条件不正确。它将首先检查第一个条件strcmp(username, user) != 0。如果为 true,它将检查第二个条件,但如果不是,它将结束循环,因为条件AND无论如何都没有机会计算为 true。因此,如果用户名正确,则此条件的计算结果将为 false,并且不会评估密码。您可以使用逻辑 OR (||) 来检查这两个条件。AND 和 OR 之间的区别如下:

如果密码和用户名错误,则拒绝访问。 -> 仅在两者都错误时才拒绝

如果密码或用户名错误,则拒绝访问。 -> 如果错了就拒绝

最新更新