简体   繁体   English

堆栈溢出运行时错误C ++

[英]stack overflow runtime error c++

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). 我需要密码至少为6个字符,但我也将密码限制为最多10个(不是必需的,但希望如此)。

The program works great and my other validations work until I try to add a password with more than 10 characters. 该程序运行良好,其他验证也有效,直到尝试添加超过10个字符的密码为止。 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. 运行时检查失败#2-变量'password'周围的堆栈已损坏。

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;
 }

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. 如果使用cstrings,操作符<<将读取一个字符串, 如果有足够的空间, 则会在缓冲区的末尾自动添加空字节字符。

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. 您将缓冲区分配为11,因此当输入的密码大于10时,将不存在终止字符串的空字节,从而导致strlen等问题。 Indeed, what strlen does is simply reading the input and incrementing a counter until a \\0 is encountered. 确实, strlen所做的只是读取输入并递增计数器直到遇到\\0

You have now two choices: 您现在有两个选择:

  1. keep going with cstring and augment the size of the buffer (high enough to avoid surprises), 继续使用cstring并增加缓冲区的大小(足够大以避免发生意外),
  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 ). 切换到c ++的string类,它是一个可以动态增加的char数组(强烈建议使用, 这里是开始链接 )。

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. validatePassword调用validateLength来检查strlen(pass) <= 10并且只有在密码正确时才可以退出第一个循环。

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). 另一个改进是将密码的大小传递给函数,以避免在任何地方调用strlen (在C语言中,总是使用char *参数传递该大小是很常见的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM