#include <iostream>
#include <string>
#include <cctype>
usingnamespace std;
constint MIN_CHARS = 6;
void get_password();
void verifyPassword(string);
int main()
{
cout << "(Passwords must be at least six character long, contain at least\n";
cout << "contain at least one uppercase and one lowercase letter,and should\n";
cout << "have at least have one digit.) Enter a password:";
get_password();
}
void get_password()
{
string str;
do
{
getline(cin, str);
if (str.length() < MIN_CHARS)
cout << "Password must be at least 6 characters! Re-enter password:\n";
} while (str.length() < MIN_CHARS);
verifyPassword(str);
}
void verifyPassword(string funcstr)
{
cout << funcstr << endl;
int verifyDigit = 0;
int verifyUpper = 0;
int verifyLower = 0;
for (int count = 0; count < funcstr.length(); count++)
{
if (isdigit(funcstr[count]))
verifyDigit++;
if (isupper(funcstr[count]))
verifyUpper++;
if (islower(funcstr[count]))
verifyLower++;
}
cout << "VerifyDigit: " << verifyDigit << endl;//These statements are checking what values are here for testing purposes
cout << "VerifyUpper: " << verifyUpper << endl;
cout << "VerifyLower: " << verifyLower << endl;
if (verifyDigit == 0)
{
cout << "Your password needs at least one digit. Re-enter password: ";
get_password();
}
if (verifyUpper == 0)
{
cout << "VerifyDigit: " << verifyDigit << endl;//these are also for testing purposes.
//As you can see the values are different then the
//ones checked right before these if statements. Why?
cout << "VerifyUpper: " << verifyUpper << endl;
cout << "VerifyLower: " << verifyLower << endl;
cout << "Your password needs at least one uppercase character. Re-enter password: ";
get_password();
}
if (verifyLower == 0)
{
cout << "Your password needs at least one lowercase character. Re-enter password: ";
get_password();
}
}
I understand this is probably a relatively simple problem but I'm still learning how the language works so I don't want to spend hours trying to find a problem that is probably easy and I am just ignorant of the reasoning behind it because I don't know enough about the language. Above is the code I developed which is a program that prompts the user to enter a password and then proceeds to verify that the password follows the correct specs(password must be 6 chars, have at least one digit, uppercase letter, and lowercase letter.) If the password fails to meet any point the program informs the user why and asks for a re entry. My problem: When I run the program like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
(Passwords must be at least six character long, contain at least
contain at least one uppercase and one lowercase letter,and should
have at least have one digit.) Enter a password:password
password
VerifyDigit: 0
VerifyUpper: 0
VerifyLower: 8
Your password needs at least one digit. Re-enter password: Password5
Password5
VerifyDigit: 1
VerifyUpper: 1
VerifyLower: 7
VerifyDigit: 0
VerifyUpper: 0
VerifyLower: 8
Your password needs at least one uppercase character. Re-enter password:
As you can see for some reason despite entering a correct password I still get the wrong result. Here it states that I need an uppercase however I did put an uppercase as "Password5." The program seems to be retaining the data from the first time it loops, but I thought variable values were not retained between function calls?
When you enter Password5, line 54 condition is triggered and function on line 57 is called. Curresnt function execution is paused. It will resume when called function exits. And then it will trigger condition on line 50.
Avoid recursive calls. Avoid multiple responsibilities. Your verify password should do only what it is named for: verify password. It should not get new password. On the other hand, get_password should not have part of password veryfuing in it.
// ↓↓↓ In the future you would like to actually get string, would you?
std::string get_password()
{
std::string str;
do {
std::getline(std::cin, str);
bool correct = verifyPassword(str);
if( !correct) std::cout << "Re-enter password: ";
} while (not correct);
return str;
}
bool verifyPassword(const std::string& funcstr) //Avoid copy
{
//...
//Do usual stuff
if (funcstr.length() < MIN_CHARS) {
std::cout << "Password must be at least 6 characters!\n";
returnfalse;
}
if (verifyDigit == 0) {
std::cout << "Your password needs at least one digit. \n";
returnfalse;
}
//...
returntrue; //Everything passes
}