简体   繁体   中英

Problems with a Do-While Loop in C

I extremely new at coding and I'm tearing my hair out trying to get this code to loop (until the correct criteria has been met.. upper/lower case letters and a digit) am I putting the do while loop in the right place??

Many Thanks in advance for any help received..

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

main()
{
    int i;
    int hasUpper, hasLower, hasDigit;
    char password[20];

    hasUpper = hasLower = hasDigit = 0; // initialising these three variables to false (o)

    printf("Please enter a alpha numeric password with upper and lower case\n");
    scanf(" %s", password);

    do {
        for (i = 0; i < strlen(password); i++) {
            if (isdigit(password[i])) {
                hasDigit = 1;
                continue;
            }

            if (isupper(password[i])) {
                hasUpper = 1;
                continue;
            }

            if (islower(password[i])) {
                hasLower = 1;
                continue;
            }
        }

        printf("Not so good, try again!");
        scanf(" %s", password);
    } while ((hasDigit) && (hasLower) && (hasUpper)==1);

    // This loop will only execute if all three variables are true

    if ((hasUpper) && (hasLower) && (hasDigit)) {
        printf("Great password!");
    }

    return 0;
}

Your while conditions are faulty, also the variables need clearing after each attempt and the print out for a fail needs a check. Also, moving your scanf() to the start of the loop makes things easier and removes the need for the extra one outside of the loop on the initial input.

#include <stdio.h>
#include <string.h>
#include <stdbool.h>    // Use for boolean types

int main(int argc, const char argv[]) {    // Correct function signature
    int i = 0, plen = 0;
    bool hasUpper = false, hasLower = false, hasDigit = false;    //Change types to boolean
    char password[20] = {0};    // Initialise string with all '\0'

    printf("Please enter an alpha-numeric password with upper and lower case\n");

    do {
        hasUpper = false;    // Clear boolean variables for each new password
        hasLower = false;
        hasDigit = false;

        scanf("%s", password);
        password[19] = 0;    // ensure string is correctly terminated with '\0'
        plen = strlen(password); // Get the string length *once* per new password

        for (i = 0; i < plen; ++i) {
            if (isdigit(password[i])) {    // Use 'if...else' in place of 'continue'
                hasDigit = true;
            } 
            else if (isupper(password[i])) {
                hasUpper = true;
            }
            else if (islower(password[i])) {
                hasLower = true;
            }
        }

        if ((!hasDigit) || (!hasLower) || (!hasUpper)) {    // Check the booleans before printing fail message
            printf("Not so good, try again!");
            for (i = 0; i < 20; ++i) {
                password[i] = 0;    // Clear the string with all '\0'
            }
        }
    } while ((!hasDigit) || (!hasLower) || (!hasUpper));   // Correct the logic here

    printf("Great password!");   // Remove the unneeded boolean check here
    return 0;
}

I would also consider replacing the if...continue pattern with an if...else if as use of continue is bad practice.

The code is not working because of a few logical problems.
First of all, the do while loop will continue even if all the values ( hasDigit , hasLower and hasUpper ) are 1 ( the condition in while is wrong ).

You are also printing the "Not so good" statement even if all of them are 1.

There is also the problem that if you enter a bad password one time, the values are assigned to the three variables, but they are not reset to 0 and thus, when you enter a new password, the values of the three variables will be the values it obtained in the previous loop ( that is, if in your previous password, if any one of them had been set to 1, then the value will remain 1 even for the next password ).

Now, Here is a code in which I have fixed the errors

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

int main()
 {

    int i;
    int hasUpper,hasLower,hasDigit;
    char password [20];
    hasUpper=hasLower=hasDigit=0; // initialising these three variables to false (o)

    printf("Please enter a alpha numeric password with upper and lower case\n");
    scanf(" %s", password);

    do
     {
       hasUpper=hasLower=hasDigit=0;   // you need to initialize them to 0 here as well

       for(i=0;i<strlen(password); i++)
         {
            if (isdigit(password[i]))
             {
               hasDigit = 1;
             }

            if (isupper(password[i]))
             {
               hasUpper = 1;
             }

            if (islower(password[i]))
             {
               hasLower = 1; 
             }
         }

       if( ( (hasUpper) && (hasLower) && (hasDigit) ) !=1 )  // with this if statement, only if all the criteria are not met, the printf is executed
         { 
           printf("Not so good, try again!");
           scanf(" %s", password);
         }

     }while( ( (hasDigit) && (hasLower) && (hasUpper) ) !=1 );  // loop continues as long as all of them are not 1

    // This statement will only execute if all three variables are true

    printf("Great password!");

    return 0;
 }

Note that I have removed the if condition from

if  ((hasUpper)&&(hasLower)&&(hasDigit))
{
    printf("Great password!");
}

This is because the program comes out of the do while loop only when you enter a Good Password, and thus there is no longer a need for that if statement, just the printf is enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM