I am writing a program that takes a password as input and validates based on the following criteria:
The validation function successfully checks for all of the criteria except for lowercase letters even though the method is the same.
P.S. I am aware that using namespace standard is considered bad practice but for the sake of this program, it shouldn't cause any issues to my knowledge.
Main:
#include <iostream>
#include <string>
#include "Passwords.h"
using namespace std;
int main()
{
string password; //string for user input
bool longEnough, foundUpper, foundLower, foundDigit; //booleans to validate password
for(int i = 3; i > 0; i--) //loop 3 times or until valid password is entered
{
longEnough = false; //reset bools to false
foundUpper = false;
foundLower = false;
foundDigit = false;
getInput(password); //calling getInput function
if(validatePass(password, longEnough, foundUpper, foundLower, foundDigit) == true) //check if the password is valid
{
getValidOutput(password); //calls function to display output for valid password
exit(0); //end program
}
else
{
getInvalidOutput(password, longEnough, foundUpper, foundLower, foundDigit); //calls function to display output for invalid password
cout << "You have " << i-1 << " more attempts.\n";
}
}
cout << "You have run out of attempts, the session has been locked.";
exit(0); //end program
}
Header file:
#ifndef PASSWORDS_H_INCLUDED
#define PASSWORDS_H_INCLUDED
using namespace std;
void getInput(string& password) //prompts and receives user input for password
{
cout << "Please enter a password with at least 8 characters, one uppercase, one lowercase, and one digit: ";
cin >> password;
}
bool validatePass(string password, bool& longEnough, bool& foundUpper, bool& foundLower, bool& foundDigit) //checks if password is valid
{
if(password.length() >= 8) //check for length
{
longEnough = true;
}
for(int i = 0; i < password.length(); i++) //check each character
{
char position = password.at(i); //set current character
if(isupper(position) == true) //check for uppercase letters
{
foundUpper = true;
}
if(islower(position) == true) //check for lowercase letters
{
foundLower = true;
}
if(isdigit(position) == true) //check for digits
{
foundDigit = true;
}
}
if(longEnough == true && foundUpper == true && foundLower == true && foundDigit == true) //return true if valid, return false otherwise
{
return true;
}
else
{
return false;
}
}
void getValidOutput(string password) //output if the password is valid
{
cout << "The password \"" << password << "\" is valid.";
}
void getInvalidOutput(string password, bool longEnough, bool foundUpper, bool foundLower, bool foundDigit) //output if the password is invalid
{
cout << "The password \"" << password << "\" is invalid for the following reasons:\n";
if(longEnough == false)
{
cout << "The password has less than 8 characters\n";
}
if(foundUpper == false)
{
cout << "The password does not contain an uppercase letter\n";
}
if(foundLower == false)
{
cout << "The password does not contain a lowercase letter\n";
}
if(foundDigit == false)
{
cout << "The password does not contain a digit\n";
}
}
#endif // PASSWORDS_H_INCLUDED
Your checks are wrong:
if(isupper(position) == true) //check for uppercase letters { foundUpper = true; }
int isupper( int ch );
Checks if the given character is an uppercase character as classified by the currently installed C locale. In the default "C" locale,
std::isupper
returns a nonzero value only for the uppercase letters (ABCDEFGHIJKLMNOPQRSTUVWXYZ).
In your comparison true
is promoted to int
, ie 1
, and any nonzero value different from 1
returned from isupper
will make isupper(position) == true
yield false
, because eg 2 == 1
is false
.
Change the comparisons to
if(isupper(position))
{
foundUpper = true;
}
int
can be converted to bool
and then any nonzero value yields true
.
Same for islower
and isdigit
.