2017-01-22 5 views
0

Я пишу программу для класса для проверки пароля. Мне нужно, чтобы пароль был как минимум 6 символов, но я также ограничиваю его максимум 10 (не обязательно, а хотел).ошибка переполнения стека стека C++

Программа отлично работает, и мои другие проверки работают до тех пор, пока я не попытаюсь добавить пароль с более чем 10 символами. Я могу пройти и снова ввести новый пароль, и я получаю сообщение о том, что он теперь является действительным паролем. Но тогда я получаю следующее сообщение об ошибке:

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

Я могу обойти ошибки, если установить ширину, но я знаю, что это не правильный способ справиться с этим. Также я бы подумал, что, установив ширину, пользователь не сможет ввести ничего, кроме этого размера.

Вот мой код:

#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; 
} 
+1

По внешнему виду, измените объявление переменной с 'char password [11]' на 'std :: string password', и вам хорошо идти. Буфер 'char' может быть слишком коротким для хранения ваших данных. – hauron

+0

Не смешивайте C и C++. Someteimes У вас есть C char *, иногда std :: string. Этот фильм не доволен. –

ответ

2

с cstrings, оператор << будет читать строку и автоматически добавляет нуль-байтовый символ в конце буфера если есть достаточно места.

Вы выделяете буфер из 11, поэтому, когда введенный пароль превышает 10, нулевой байт, заканчивающий строку, не будет присутствовать, что вызовет проблемы с strlen и т. Д. Действительно, то, что делает strlen, просто считывает вход и увеличивает счетчик до тех пор, пока не встретится \0.

Вы едите сейчас два варианта:

  1. продолжать идти с cstring и расширяющего размером буфера (достаточно высокого, чтобы избежать сюрпризов),
  2. переключателя в string класса C++, который является массивом из char, способного динамически увеличиваться (настоятельно рекомендуется, here is a link to get started).

Кроме того, в отношении кода: у вас есть много ненужных вещей. Например:

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 

} 

может быть заменен:

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 вызовов validateLength, который проверяет, что strlen(pass) <= 10 и вы можете выйти из первого цикла, только если пароль правильный.

Еще одним преимуществом было бы передать размер пароля в соответствии с вашими функциями, чтобы избежать повсеместного вызова strlen (обычно в C всегда передается размер с аргументом char *).

+0

Я просмотрел вашу ссылку, но я не уверен, что понимаю ее. Я очень новичок в C++ .. поэтому, когда я меняю пароль char [10] на строковый пароль; Я получаю ошибки при каждой ссылке на пароль. Я не знаю, как это исправить. –

+0

какая ссылка?Я обновил ответ ^^ – Derlin

+0

, теперь вы можете просто изменить 'char password [11]' '' пароль пароля [50] '. Если вы хотите использовать 'string', вам также необходимо изменить подпись ваших методов, то есть заменить' validateXX (char * pass) 'на' validateXX (string pass) '. – Derlin

Смежные вопросы