Trying to write a program that accepts a file of passwords and tests it for certain requirements, those requirements being: Has at least one upper case letter, has at least one lower case letter, has at least two digits, has no special characters, and is between 8 and 15 letters. The file consists of the passwords:
abcABC1
abcdefABCDEF1234
ASDFGHJKL
asdfghjkl
123456789
snowSNOW
snowSNOW4
2snowSNOW4
snowSNOW34
ritRIT$123
(snow34SNOW)
%$.,/*&^%$
RIT2011isgreat
MYcatOliveris10
winterIS22cold
Supercalifragilisticexpialidocious22

My issue is that it runs the validation but only lists the first failed cout statement when it fails instead of listing all of the issues, such as

What Mine Does
Proposed password: %$.,/*&^%$

Must have at least one lower case letter
Password is invalid

What it should do
Proposed password: %$.,/*&^%$

Must have at least one lower case letter
Must have at least one upper case letter
Must have at least two digits
Must start with a letter
Must not have any special characters
Password is invalid

Im fairly new at c++ and was wondering if anyone had any advise on how to call each function and have each password run through every function?

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>


using namespace std;


//function prototypes
bool checkLength(int length);
bool lowerCase(int length, string line);
bool upperCase(int length, string line);
bool beginLetter(int length, string line);
bool correctDigits(int length, string line);
bool specialChar(int length, string line);

int main ()
{
    string fileName; //text file name
    ifstream myFile; //creating a input stream
    string line; //password lines from input file
    int length; //determine string length



    cout << "Enter password file: "; //user enters file name (must be in same directory as .cpp)
    cin >> fileName;

    myFile.open(fileName.c_str()); //converts filename to string

    if(myFile.is_open())//Checks to see if the file opened
    {
        cout << "File exists and is ready to be used\n" << endl;//confirms file is open

        while(!myFile.eof())//while not at the end of the file
        {
            getline(myFile, line); //read lines from program
            length = line.length(); //determine length of each line

            cout << "Proposed Password: " << line << endl; //password shown from file


            //functions being called to test validity
            if(checkLength(length) == false || lowerCase(length, line) == false || upperCase(length, line) == false || beginLetter(length, line) == false || correctDigits(length, line) == false || specialChar(length, line) == false)
            {
                cout << "Password is Invalid\n" << endl; //if statements come back false the password is invalid
            }
            else
            {
                cout << "Password is Valid\n" << endl; //if statments come back true the password is valid
            }
        }

        myFile.close(); //close file
    }
    else
    {
        cerr << "Unable to open file " << fileName << " - does not exist in current directory"; //if the file doesnt open, throw an exception
        return 1; //close program
    }

    return 0; //end program
}
//Function to check the length of the password
bool checkLength(int length)
{
    //function variables
    bool validLength;

    if ((length >= 8) && (length <= 15)) //checks to see if password is between 8 and 15 characters
    {
        validLength = true;
    }
    else
    {
        validLength = false;
        cout << "   Error - The password must be between 8 and 15 characters" << endl; //output if false
    }

    return validLength; //returns value
}
//function to check for at least one lower-case letter
bool lowerCase(int length, string line)
{
    //function variables
    bool validLower;
    int count = 0;

    char password[length+1];
    strcpy(password, line.c_str());//convert string to char array

    for (int j = 0; j < length; j++ )
    {
         if (islower(password[j]))
        {
            count++; //count number of valid lower case letters
        }
    }

    if (count < 2)
    {
        cout << "   Error - Must have at least 1 lower Case letter" << endl;//output if false
        validLower = false;
    }
    else
    {
        validLower = true;
    }

    return validLower; //return value
}
//function to test for one upper-case letter
bool upperCase(int length, string line)
{
    //function variables
    bool validUpper;
    int count = 0;

    char password[length+1];
    strcpy(password, line.c_str());//convert string to char array

    for (int i = 0; i < length; i++ )
    {
         if (isupper(password[i]))
        {
            count++; //count number of upper case letters
        }
    }

    if (count < 2)
    {
        cout << "   Error - Must have at least 1 Upper Case letter" << endl; //output if false
        validUpper = false;
    }
    else
    {
        validUpper = true;
    }

    return validUpper; //return value
}
//function to see if first character is a letter
bool beginLetter(int length, string line)
{

    //function variables
    bool validBegin;

    char password[length+1];
    strcpy(password, line.c_str());//convert string to char array

    if(isupper(password[0]) || islower(password[0]))
    {
        validBegin = true;
    }
    else
    {
        validBegin = false;
        cout << "   Error - Must begin with a letter" << endl; //output if false
    }

    return validBegin; //return value
}
//Function to test for characters that are not alphanumeric
bool specialChar(int length, string line)
{
    //function variables
    bool validChar;
    int count = 0;

    char password[length+1];
    strcpy(password, line.c_str());//convert string to char array

    for (int i = 0; i < length; i++ )
    {
        if (ispunct(password[i]))
        {
            count++; //count number of special characters
        }
    }

    if (count > 0)
    {
        cout << "   Error - Must not have any special characters" << endl; //output if false
        validChar = false;
    }
    else
    {
        validChar = true;
    }

    return validChar; //return value
}
//Function to test for at least two digits
bool correctDigits(int length, string line)
{

    //function variables
    bool validDigits;
    int count = 0;

    char password[length+1];
    strcpy(password, line.c_str()); //convert string to char array

    for (int i = 0; i < length; i++ )
    {
        if (isdigit(password[i]))
        {
            count++; //count number of digits
        }
    }

    if (count < 2)
    {
        cout << "   Error - Must have at least two digits" << endl; //output if false
        validDigits = false;
    }
    else
    {
        validDigits = true;
    }

    return validDigits; //return value
}

checkLength(length) == false || lowerCase(length, line) == false || upperCase(length, line) == false || beginLetter(length, line) == false || correctDigits(length, line) == false || specialChar(length, line)

When this is executed, from left to right, as soon as the final outcome is known for sure, all the rest will be skipped.

So as soon as one of these comes up true (in your case, lowerCase(length, line) == false is the first coming up true), all the rest are skipped because it's now known that the final result of the || chain must be true. This is known as short-circuit evaluation.

You will have to rewrite your code to ensure that every check you want actually does get called.

Edited 2 Years Ago by Moschops

Ah ok I see, would there be any way to write the function call with how my functions are currently written to have multiple errors pop up? I changed it to && and true to see if it would make any difference but it did not

Instead of putting all those statements in one bit line separated by either || or && you should call them as individual statements.

 bool a,b,c,d,e,f;
 a = checklength(length);
 b = lowerCase(length,line);
 c = upperDate(length,line);
 d = beginLetter(length, line);
 e = correctDigits(length, line);
 f = specialChar(length, line);

 if( a || b || c || d || e || f)
 {
    // error
 }
This article has been dead for over six months. Start a new discussion instead.