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

在C中使用Do..while循环登录,c,string,loops,do-while,C,String,Loops,Do While,我需要做一个程序,要求用户名和密码,如果他们都是正确的继续菜单。 由于某种原因,当前输入的正确的用户名和错误的密码仍然会提示我进入菜单,但是如果我输入的错误的用户名和正确的密码则不会。如果我第一次输入正确的用户名和密码,它总是会返回“错误的用户名或密码请重试”。以下是代码: #include <stdio.h> #include <string.h> #define user "kaiti" #define pass "123Pass!" int main

我需要做一个程序,要求用户名和密码,如果他们都是正确的继续菜单。 由于某种原因,当前输入的正确的用户名和错误的密码仍然会提示我进入菜单,但是如果我输入的错误的用户名和正确的密码则不会。如果我第一次输入正确的用户名和密码,它总是会返回“错误的用户名或密码请重试”。以下是代码:

#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.\n\nWelcome Mrs.Kaiti!\n\nWhat would you like to do?");
    //-----END OF LOGIN PHASE-----
#包括
#包括
#定义用户“kaiti”
#定义pass“123Pass!"        
int main()
{
字符用户名[20],密码[20];
//-----登录阶段-----
printf(“请输入用户名:”);
scanf(“%s”,用户名(&s));
printf(“\n请输入密码:”);
scanf(“%s”和密码);
做
{
printf(“错误的用户名或密码重试!\n”);
printf(“\n请输入用户名:”);
scanf(“%s”,用户名(&s));
printf(“\n请输入密码:”);
scanf(“%s”和密码);
}
while(strcmp(用户名,用户)!=0和strcmp(密码,通行证)!=0);
printf(“正确的用户名和密码。\n\n欢迎Kaiti夫人!\n\n您想做什么?”;
//-----登录阶段结束-----
您需要一个
while(condition){/*body*/}
循环


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

您的布尔表达式是错误的。有效大小写为
strcmp(username,user)==0&&strcmp(password,pass)==0
(用户名和密码正确)。其倒装形式是strcmp(用户名、用户)!=0 | | strcmp(密码、通行证)!=0(表示“任一条件未满足”)

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

  • 如果使用while循环,它将始终在检查while条件之前运行循环。因此,在循环之前插入什么并不重要,因为它将始终在第一次运行时跳转到循环中。您可以使用while循环解决它,或者将所有内容都放在do-while循环中,然后稍作更改
  • while循环中的条件不正确。它将检查第一个条件
    strcmp(用户名,用户)!=0
    第一个。如果为真,它将检查第二个条件,但如果不是,它将结束循环,因为条件
    无论如何都没有机会计算为真。因此,如果用户名正确,此条件将计算为假,密码将不会计算。您可以使用逻辑OR(
    |
    )检查这两种情况。与或之间的区别如下:
如果密码和用户名都错误,则拒绝访问。->仅当密码和用户名都错误时才拒绝访问


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

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] = '\0';
        password[m] = '\0';

        valid = valid && strcmp( username, USER ) == 0 && strcmp( password, PASS ) == 0;

        if ( !valid )
        {
            printf("\nWrong username or password try again!\n\n");
        }
    } while ( !valid );

    printf("Correct username and password.\n\nWelcome Mrs.Kaiti!\n\nWhat would you like to do?");
    //-----END OF LOGIN PHASE-----  return 0;
}
在第一次尝试中,用户输入了错误的密码


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

循环的第一条语句是printf(“错误的用户名或密码,请重试!\n”);那么您想要什么?!您所做的就是您得到的。
scanf(“%s”,&username);
-->
scanf(“%19s”,username)
您的逻辑似乎有点缺陷,在打印“错误的用户名或密码”之前检查用户名/密码是否正确不是更好吗?即,使用普通的
while do
循环而不是
do while
?您知道
strcmp()吗
如果字符串匹配,则实际返回0?如果给出了错误的用户名或密码,则应指示用户重试。然而,while循环应仅在给出错误的用户和密码时启动,而不是始终。我如何解决此问题?你错了。他想要一个do-while循环,实际上他应该使用do-while循环。我相信错误消息ge(无效凭据)应在出现错误后出现…因此,在循环外部请求凭据,检查这些凭据,如果错误,则通知用户并获取新凭据。
#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] = '\0';
        password[m] = '\0';

        valid = valid && strcmp( username, USER ) == 0 && strcmp( password, PASS ) == 0;

        if ( !valid )
        {
            printf("\nWrong username or password try again!\n\n");
        }
    } while ( !valid );

    printf("Correct username and password.\n\nWelcome Mrs.Kaiti!\n\nWhat 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?