C++ 异常:字符串下标超出范围

C++ 异常:字符串下标超出范围,c++,string,exception,C++,String,Exception,我只是尝试编写一个简单的基于控制台的登录代码,而我被指定隐藏用户的密码,我编写了代码,但我在调试时遇到异常错误。我尝试了一些方法来解决它,但是失败了,不知道该怎么办。代码似乎有点混乱。我也尝试了所有的方法 及 也没有找到解决办法。所以,在这个问题上我需要帮助 编辑:当我使用固定大小的字符数组时,它工作得很好,但由于它的固定大小和内存问题,我在 string data_handle::hidden_password() 以下代码的功能 #include <iostream> #inc

我只是尝试编写一个简单的基于控制台的登录代码,而我被指定隐藏用户的密码,我编写了代码,但我在调试时遇到异常错误。我尝试了一些方法来解决它,但是失败了,不知道该怎么办。代码似乎有点混乱。我也尝试了所有的方法

也没有找到解决办法。所以,在这个问题上我需要帮助

编辑:当我使用固定大小的字符数组时,它工作得很好,但由于它的固定大小和内存问题,我在

string data_handle::hidden_password()
以下代码的功能

#include <iostream>
#include <conio.h>
#include <exception>
#include <fstream>
#include <string>

using namespace std;


class username_data {
protected:
    string username;
    ifstream file;
public:

    int is_user_matched(string);            //the function will return the index at which the data is found
};

int username_data::is_user_matched(string user_input) {
    int index = -1;
    file.open("username.txt");                  //to open user-name file for reading file
    if (file.is_open()) {                       // if the file is open 
        for (int i = 0; getline(file, username); i++) {         // to get data from the file
            if (username == user_input) {                           //if both inputs matches then it will return the index
                index = i;
                break;
            }
        }
        file.close();                   //closing the file
    }
    else {                          //if the file is not open then it will throw user defined exception that file does not exist
        throw "user-name file not found";
    }
    return index;           //it will return the index at which the user-name is found otherwise it will return -1
}





class admin {
public:
    bool check_admin(string);       //function to check whether administrator logged in or not
};

bool admin::check_admin(string username) {
    string file_data;               //to get data from administrator file
    bool is_found = false;          //to check whether the data is found in the file and return whether it is present or not
    ifstream admin_file;            //to open the file
    admin_file.open("admin.txt");   //opening administrator file
    if (admin_file.is_open()) {     //if administrator file is open
        while (getline(admin_file, file_data)) {        //to get data till user-name is not found or file is not giving any further data
            if (file_data == username) {        //if data is matches with the passed user-name then it will break the loop
                is_found = true;        //if data is found then the boolean will turn true and break the loop
                break;              //breaking the loop
            }
        }
        admin_file.close();         //closing the file
    }
    else {
        throw "administrator file not found";       //if anything wrong occurs then it will throw exception
    }
    return is_found;                //to return true or false of data
}







class password_data {
    string password;
    ifstream file;
public:
    int is_password_matched(string);            //it will return the index at which the entered password is found
};


int password_data::is_password_matched(string user_input) {
    int index = -1;                         //if the data is not found then it will return -1
    file.open("password.txt");              //opening the password file
    if (file.is_open()) {                   //it will return true if the file is open for reading
        for (int i = 0; getline(file, password); i++) {     //this will get input from the file and checks until the last data or the relevant file is found
            if (password == user_input) {               //if data is matched
                index = i;                  //then it will store the input and the loop will broken down
                break;                      //to break the loop
            }
        }
        file.close();               //to close the program it will save from force closing of file which may leads to data corruption
    }
    else {
        throw "password file not found";        //it will throw exception
    }
    return index;                       //to return the found index
}







class data_handle  {
    string entered_username;
    username_data handler1;         //to handle user-name data
    password_data handler2;         //to handle password data
    string hidden_password();       //to return the string about the password
public:
    bool is_admin_logged_in;
    void user_input();              //this function will get user input
};

string data_handle::hidden_password() try {
    string entered_password;
    for (int i = 0; true; i++) {
        entered_password[i] = _getch();
        if (entered_password[i] != 8 && entered_password[i] != 13) {        //8 is the ASCII of backspace and 13 is the ASCII of enter

            cout << '*';                //password form
        }
        else if (entered_password[i] == 8) {            //backspacing for erasing password 
            if (i >= 1) {
                cout << "\b \b";            //only erase stars from console window
                i -= 2;                     /* just for array overwriting -2 because when we press backspace it goes one index up(-1 for that) and
                                            to go to the variable to be changed (-1 again for that too) so as a whole -1-1=-2*/
            }
            else {
                i = -1;                     /* if the password array went to 0 index then by pressing backspace the index of array will go in negative values to restore them to 0
                                             -1 is used because if index went -1 then when the loop starts the index i will be restored to 0 index*/
            }
        }

        else if (entered_password[i] == 13) {
            entered_password[i] = '\0';             // if user press enter then store \0 as null character
            break;                          // terminating the loop
        }
    }
    return entered_password;
}
catch (exception ex) {              //if anything occurs like array index out of bounds
    cout << ex.what() << " occurred\n\n";
    return "";
}

void data_handle::user_input() try {
    int idx1, idx2;
    bool login_successful = false;          //to control the login
    do {
        cout << "Enter user-name :\t";
        getline(cin, entered_username);     //to get the user-name from the user
        cout << "Enter password :\t";
        idx1 = handler1.is_user_matched(entered_username);          //this function will pass the user-name to the handler for execution
        idx2 = handler2.is_password_matched(hidden_password());     //to get the password from the user it will return the string and then pass it to the handler function
        if ((idx1 != -1 && idx2 != -1) && idx1 == idx2) {       //if handlers methods returned -1 then data does not exists in the file if any index is returned then it is in the file and both user-name and password must have same index
            login_successful = true;                //if it is true then the login will be successful
            admin login_check;              //a class to check whether administrator logged in or anyone else
            is_admin_logged_in = login_check.check_admin(entered_username);     //running the function
        }
        if (!login_successful) {                    //if login is not successful then it will print login failed
            cout << "\n\nLogin Failed . . .\n\n";
        }
        else {                                      //else it will print login successful
            cout << "\nlogin successful!\n";
        }
    } while (!login_successful);                    //the loop will continue till user continues to enter wrong password
}
catch (const char * message) {                      //if any exception is thrown it will be handled by this catch like file is not opened then this setting will run
    cout << message << " occurred\n";
}
catch (exception ex) {              //if any other exception occurs
    cout << "\n\n" << ex.what() << "occurred . . .\n\n";
}

默认构造的字符串为空。您不能使用输入的_密码[i]向其添加字符,因为其中没有字符。如果存在一个字符,它将替换该字符,但在您的情况下没有

将字符添加到字符串末尾的一种方法是

entered_password += _getch();
完成后,后面对输入的\u密码[i]的引用将引用此字符,并且应该可以。

在隐藏的\u密码中,输入的\u密码最初为空,因此使用输入的\u密码[i]来分配不添加字符是超出范围的。要添加字符,您需要使用输入的密码+=。。。或输入了密码。请按回。。。相反


因此,应该使用std::cin.get而不是_getch从控制台读取字符。或者更好的方法是,您应该使用std::getline一次性将整个密码读入entered_password,让控制台处理backspaces,然后使用std::getline处理ENTER,然后您可以使用entered_password[…]循环输入的_password的字符根据需要。

这是因为我使用字符串作为字符数组,我想这是由于使用固定大小的字符数组时进行了索引,所以效果很好。我也在更新问题。@tadman我更新了问题。谢谢你的帮助。如何进一步优化此代码。如果需要的话?