Исключение: строковый индекс вне диапазона - PullRequest
0 голосов
/ 03 апреля 2020

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

строковый индекс вне диапазона и C ++: выражение: строковый индекс вне диапазона

и не нашел решения для этого. Итак, мне нужна помощь по этой проблеме.

Редактировать: Когда я использовал массив символов фиксированного размера, он работал нормально, но из-за его фиксированного размера и проблемы с памятью я изменил его с помощью строковой переменной в

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

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Построенная по умолчанию строка пуста. Вы не можете добавлять символы к нему, используя entered_password[i], потому что там нет символов. Он заменит символ, если он существует, но в вашем случае его нет.

Один из способов добавить символ в конец строки - это

entered_password += _getch();

Как только это будет сделано, последующие ссылки на entered_password[i] будут ссылаться на этот символ и должны быть в порядке.

1 голос
/ 03 апреля 2020

В hidden_password(), entered_password изначально пусто, поэтому использование entered_password[i] для назначения (не добавления) символов выходит за пределы. Чтобы добавить символы, вам нужно использовать entered_password += ... или entered_password.push_back(...).

В этом отношении вам следует использовать std::cin.get() вместо _getch() для чтения символов из консоли. Или, лучше, вы должны использовать std::getline() для считывания всего пароля в entered_password в одном go (пусть консоль обрабатывает пробелы, а std::getline() обрабатывает ENTER ), а затем вы можете l oop через символы entered_password, используя entered_password[...] при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...