Имеется структура
struct User {
string login;
string password;
};
Стоит задача сделать примитивную авторизация пользователя. Т.е. создается файлик, в него записывается заполненный объект вышеуказанной структуры, а при последующих запусках производится запрос логина+пароля, считываются данные из файлика и сравниваются. Код:
#include
using namespace std;
struct User {
string login;
string password;
};
void main ()
{
SetConsoleCP (1251); // установка универсальной кодировки
SetConsoleOutputCP (1251);
string path;
int realsize=0;
User u;
vector
do
{
system("cls");
cout<<"Укажите, на каком диске находится файл с регистрационными данными:
";
getline(cin, path);
path += ":\\users.txt";
ifstream fin(path, ios_base::binary | ios_base::in);
if (fin.is_open())
{
cout<<"Отлично, ваш файл найден!
";
fin.read((char*)&u, sizeof(User));
U.push_back(u);
fin.close();
cout << "Введите логин:
";
getline(cin, u.login);
cout << "Введите пароль:
";
getline(cin, u.password);
if (!U.at(0).login.compare(u.login) && !U.at(0).password.compare(u.password))
{
cout << "Вы авторизованы!
";
}
else
{
cout << "Вы не авторизованы!
";
}
exit = true;
}
else
{
cout << "Файл не найден и будет создан";
ofstream fout (path, ios_base::binary | ios_base::out);
if (fout.is_open())
{
cout << "Введите логин:
";
getline(cin, u.login);
cout << "Введите пароль:
";
getline(cin, u.password);
fout.write((char*)&u, sizeof(User));
fout.close();
cout << "Файл создан и данные внесены!
";
}
else
{
cout << "Ошибка при создании файла! Работа приложения будет завершена.
";
exit = true;
}
}
} while(!exit);
system("pause");
}
Вся беда в том, что при выполнении данного кода появляется ошибка:
Необработанное исключение по адресу 0x0FDECCC8 (msvcp110.dll) в test.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x0067ADE4.
Кадры стека вызовов:
Путем экспериментов установлено, что замена использования вектора на простой динамический массив никак не влияет на ошибку (т.е. она по-прежнему появляется), а вот замена использования string на char * приводит к устранению проявления данной ошибки. Погуглив, я пришел в выводу, что возникает какая-то ошибка в деструкторе string (могу ошибаться). Может кто-нибудь прояснить ситуацию и дать рекомендации по корректному использованию типа string в данного рода задачах?
Ответ
Самый простой способ (как уже упомянул в комментарии @pavel) - использовать текстовый режим работы с файлом и операторы форматированного ввода/вывода (operator<<, operator>>) для чтения/записи std::string из/в потока.
Чтение:
ifstream fin(path);
if (fin) {
fin >> u.login >> u.password;
}
Запись:
ofstream fout(path);
if (fout) {
// Разделители нужны для последующего считывания
fout << u.login << " " << u.password << "
";
}
При этом данный подход накладывает некоторые ограничения на строки: как минимум они не должны содержать в себе символы пробельной группы, т.к. такой символ будет расценен как разделитель.
Функции istream::read, ostream::write в этом случае не используются вовсе. Причина, по которой они не работают как надо указана в ответе @gbg.
Комментариев нет:
Отправить комментарий