0

I am writing a program for class for a password validator. I need the password to be at least 6 characters, but I am also limiting it to a max of 10 (not required but wanted to).

The program works great and my other validations work until I try to add a password with more than 10 characters. I can go through and reenter a new password, and I get the message that it is now a valid password. But then I get a the following error:

Run-Time Check Failure #2 - Stack around the variable 'password' was corrupted.

I can get around the error if I set the width, but I know this isn't the correct way to handle it. Also I would think that by setting the width that the user would not be able to enter anything other than that size.

Here is my code:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cctype>

using namespace std;

//Function prototypes
bool validatePassword(char *);                      //function to test pw requirements
bool validateUppercase(char *);                 //function to test for upper case value
bool validateLowercase(char *);                 //function to test for lowercase value
bool validateNumber(char *);                    //function to test for a number value
bool validateLength(char *);                    //function to test for password length

int main()
{
    //Variabes
    char password[11];                              //set the maximum number of char for password include the end     delimiter
    int size;                                       //size of the array

    //Prompt user to enter a password based on criteria

    cout << "Please enter a password that meets the following criteria: \n";
    cout << "1. A minimum of 6 characters up to a max of 10. \n";
    cout << "2. Contains atleast one uppercase and one lowercase character. \n";
    cout << "3. Contains atleast one number. \n\n";
    //cout << "****Please note if you have more the 10 characters \n";
    //cout << " the program will only accept the first 10***\n";
    cout << "\nPlease enter your password: ";
    cin >> password;
    //cin  >> setw(10) >> password;             //set this so I would not get a runtime error

    size = strlen(password);                        //determines the length of the password

    do
    {
        while (!validatePassword(password))     //if the functions returns a false value
        {
            cout << "\nYour password does not meet the requirements. ";
            cout << "\nEnter a new password: ";
            cin >> password;
            size = strlen(password);
        }
    } while (size > 10);

    if (validatePassword(password))
    {
        cout << "\nYour password " << password << " meets the requirements. \n";    //if the function returns a true value

    }

    system ("pause");

    return 0;

}

//This function calls the other validation functions 
bool validatePassword(char *pass)
{
int size = strlen(pass);
return (validateLength(pass) && validateUppercase(pass) &&         validateLowercase(pass) && validateNumber(pass) == true);
}

//This function validates the length of the password
bool validateLength (char *pass)
{
    int size = strlen(pass);
    if (size >= 6 && size < 10)
        return true;
    else
    {
        cout << "\n\nThe password you entered either contained to little or to many characters.";
        cout << "\nA minimum of 6 characters to a maximum of 10 is required.";
        return false;
    }
}

//This function checks to see if the password contains an uppercase char
bool validateUppercase(char *pass)
{
    int size = strlen(pass);
    for (int count = 0; count < size; count++)
    {
        if (isupper(pass[count]))
            return true;
    }

    cout << "\n\nThe password must contain at least one uppercase  character. ";
    return false;
}

 //This function checks to see if the password contains an lowercase char
 bool validateLowercase(char *pass) 
 {
    int size = strlen(pass);
    for (int count = 0; count < size; count++)
    {
        if (islower(pass[count]))
            return true;
    }

    cout << "\n\nThe password must contain at least one lowercase character. ";
    return false;
 }

//This function checks to see if the password contains an number char
bool validateNumber(char *pass)
{
    int size = strlen(pass);
    for (int count = 0; count < size; count++)
    {
        if (isdigit(pass[count]))
            return true;
    }

    cout << "\n\nThe password must contain at least one number. " ;
    return false;
 }
2
  • 1
    By the looks of it, change variable declaration from char password[11] to std::string password and you're good to go. The char buffer may be simply too short to hold your data. Commented Jan 22, 2017 at 20:55
  • Don't mix C and C++. Someteimes You have C char*, sometimes std::string. This film have not happy end. Commented Jan 22, 2017 at 21:19

1 Answer 1

2

with cstrings, the operator << will read a string and append the null-byte character automatically at the end of the buffer if there is enough space.

you allocate a buffer of 11, so when the password entered is higher than 10, the null byte terminating the string won't be present, causing problems with strlen and such. Indeed, what strlen does is simply reading the input and incrementing a counter until a \0 is encountered.

You have now two choices:

  1. keep going with cstring and augment the size of the buffer (high enough to avoid surprises),
  2. switch to the string class of c++, which is an array of char able to increase dynamically (strongly recommended, here is a link to get started).

Also, concerning the code: you have a lot of unnecessary stuff. For example:

do
{
    while (!validatePassword(password))     //if the functions returns a false value
    {
        cout << "\nYour password does not meet the requirements. ";
        cout << "\nEnter a new password: ";
        cin >> password;
        size = strlen(password);
    }
} while (size > 10);

if (validatePassword(password))
{
    cout << "\nYour password " << password << " meets the requirements. \n";    //if the function returns a true value

}

could be replaced by:

while (!validatePassword(password))
{
   cout << "\nYour password does not meet the requirements. ";
   cout << "\nEnter a new password: ";
   cin >> password;
}
cout << "\nYour password " << password << " meets the requirements. \n"; 

validatePassword calls validateLength which checks that strlen(pass) <= 10 and you can exit the first loop only when the password is correct.

Another improvement would be to pass along the size of the password to your functions in order to avoid calling strlen everywhere (it is common in C to always pass the size with a char * argument).

Sign up to request clarification or add additional context in comments.

9 Comments

I reviewed your link but I am not sure I understand it. I am very new to c++.. so when I change the char password[10] to string password; I get errors on every reference to password. I am not sure how to fix that.
for now, you can simply change char password[11] by char password[50]. If you want to use string, you also need to change the signature of your methods, i.e. replace validateXX(char * pass) by validateXX(string pass).
please, don't forget to mark the question as answered (checkmark on the left) if the answer suits you and welcome to stackoverflow!
Thank you so much!!! For now I am increasing the size since I have the validation if it is bigger then 10. But I am going to play around with changing it to string
validateXX(const string& pass) takes a string by reference, but doesn't let validateXX() modify it. validateXX(string& pass) takes a string by reference, and lets validateXX() modify it. validateXX(string pass) takes a string by value, by copying the original string; validateXX() can modify its copy of the string without changing the original string.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.