Сбой программы при попытке доступа к файлу, fstream —Stack Overflow

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

После некоторой отладки код кажется сбойным ifstream fin("dataBase.txt");

Ошибка не возвращается от компилятора.

Код для вызываемой функции:

void User_Psw::UserCheck()
{
// read from the database
ifstream fin("dataBase.txt");

while (!fin.eof())
{
fin >> Usernames[sizeOfDatabase] >> Password[sizeOfDatabase];
sizeOfDatabase++; //The Number of lines in .txt
}

// rest of the program
cout << "Username: ";
cin >> username;

getNameIndex();

cout << "Password: ";
cin >> password;

if(!PasswordMatches())
{
cout << "Access denied";
}
}

Я могу добавить больше фрагментов кода, если спросят.

0

Решение

Не использовать fin.eof() контролировать петлю. Эта функция полезна только после сбоя чтения.

Однако вероятной причиной сбоя является то, что вы назначаете Usernames[sizeOfDatabase], который может быть за Usernames.capacity(), Канонический способ добавить и пункт к std::vector это позвонить push_back().

Так как ваши контейнеры std::vector<std::string>это лучший подход …

std::string username, password;
while (fin >> username >> password)
{
Usernames.push_back(username);
Passwords.push_back(password);
++sizeOfDatabase;
}

Конечно, если вы хотите узнать количество имен пользователей или паролей после прочтения файла, вы можете позвонить Usernames.size() (который должен быть таким же, как Passwords.size()); это может избавить от необходимости сохранять sizeOfDatabase,

Лично я бы использовал один контейнер для имен пользователей и (соленые, хэшированные) пароли, а не два отдельных контейнера; или std::map<std::string, std::string> или возможно std::unordered_map<std::string, std::string>, сделать поиск пароля красивым и быстрым для каждого имени пользователя.

1

Другие решения

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

ifstream fin( "dataBase.txt",  ifstream::in );

if( !fin.good() )
{
cout << "Failed to open database file." << endl;
return;
}

Увидеть http://www.cplusplus.com/reference/fstream/ifstream/ifstream/ для дополнительной литературы.

0