Запись и чтение объектов в файл и из файла - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть класс User с двумя атрибутами std :: string.Когда я пытаюсь прочитать его из файла, из строки 222 я получаю исключение из-за исключительности: (*_Pnext)->_Myproxy = nullptr; Это происходит после функции isUserInFile()

Некоторые части моего кода:

Class User {
protected:
    std::string login;
    std::string password;
public:
    friend std::istream&operator>>(std::istream&in, User &obj) {
        //std::cout << "Логин: "; //"Login: "
        in >> obj.login;
        //std::cout << "Пароль: "; //"Password: "
        in >> obj.password;
        return in;
    }
    friend std::ostream&operator<<(std::ostream&out, User&obj) {
        out << obj.login << " " << obj.password;
        return out;
    }
    void encrypt() {
        char key[3] = { 'K','E','Y' };
        std::string buf = password;
        for (int i = 0; i < buf.size(); i++)
            buf[i] = password[i] ^ key[i % (sizeof(key) / sizeof(char))];
        password = buf;
        //buf.clear();
    }
    bool isUserInFile() {
        User user;
        std::ifstream file;
        file.open("Users.txt");
        while (!file.eof() && file.read((char*)&user, sizeof(User)))
            if (login == user.login) {
                file.close();
                return true;
            }
        file.close();
        return false;
    }
};
bool registration() {
    User user;
    std::fstream file;
    file.open("Users.txt", std::ios::in | std::ios::out | std::ios::app);
    std::cout << "Регистрация:\n"; //"Registration:\n"
    std::cin >> user;
    user.encrypt();
    if (!user.isUserInFile()) {
            file.write((char*)&user, sizeof(User));
        file.close();
        return true;
    }
    std::cout << "Пользователь с данным логином уже существует\n"; //"User with this login already exists\n"
    file.close();
    system("pause");
    return false;
}

1 Ответ

1 голос
/ 20 апреля 2019

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

Для записи в файл вы можете использовать:

file << user << std::endl;

а потом просто прочитать:

file >> user;

Чтобы это продолжало работать, вам понадобятся некоторые вещи:

  1. Пользователь никогда не должен вводить пробел в любом месте своего пароля.
  2. Вы должны убедиться, что запись и чтение всегда выполняются в одном и том же порядке.

В качестве альтернативы вы можете создать преобразование из строки и в строку по строкам:

static const char SEP1 = ' ', SEP2 = '\r';
friend std::string to_string(const User& u)
{
  std::string result = u.login + SEP1 + u.password + SEP2;
  return result;
}
explicit User(std::string line)
{
  size_t pos1 = s.find(SEP1);
  size_t pos2 = s.find(SEP2, pos1);
  login = s.substr(0, pos1);
  password = s.substr(pos1+1, pos2-pos1);
}

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

...