c++ - 堆栈溢出运行时错误c++

标签 c++

我正在为密码验证程序编写一个类程序。我需要密码至少包含 6 个字符,但我也将其限制为最多 10 个(不是必需的,但我想这样做)。

该程序运行良好,我的其他验证工作正常,直到我尝试添加超过 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;
 }

最佳答案

对于 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 * 参数传递大小)。

关于c++ - 堆栈溢出运行时错误c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41796006/

相关文章:

c++ - 为什么一个 child 类(class)单独抛出错误?顺序重要吗?

c++ - 在函数参数中连接字符串和变量?

c++ - 在指向(全局/持久)对象的指针超出范围后,对象(不是指针)的成员 vector 获取 'unset'

c++ - 是否可以使用 Xcode 进行 Linux 开发?

c++ - 为什么允许没有名字的声明?

c++ - 在 C++ 类中声明数组数据

c++ - 选择什么 VS 2010 模板?

c++ - 错误 C2760 : syntax error: unexpected token '<' , 预期 ';'

c++ - 另一个 : Undefined symbols for architecture x86_64:

c++ - 使用 std::move 返回时 "return-by-rvalue-ref"和 "return-by-value"之间的区别?