将对象写入文件和从文件读取对象
Writing and reading objects to and from file
我有一个具有两个 std::string 属性的 class 用户。当我尝试从文件中读取它时,我从第 222 行的 uxitility 中得到异常:
(*_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;
}
评论的方向正确,显示了问题所在。但是解决方案要简单得多,你已经有了流操作符,所以就用它们吧!
要写入文件,您可以使用:
file << user << std::endl;
然后简单地读给你听:
file >> user;
要继续工作,您需要一些东西:
- 用户永远不应在其密码中的任何位置输入白色-space。
- 您需要确保写入和读取始终以相同的顺序完成。
或者,您可以按照以下行创建从字符串到字符串的转换:
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);
}
然后你可以在你的 main 中读取一个数据块并简单地从中构造一个用户,或者你可以在写入之前将用户转换为字符串。这种方法的优点是您 select 分隔符并且它们在函数之间是稳定的。
我有一个具有两个 std::string 属性的 class 用户。当我尝试从文件中读取它时,我从第 222 行的 uxitility 中得到异常:
(*_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;
}
评论的方向正确,显示了问题所在。但是解决方案要简单得多,你已经有了流操作符,所以就用它们吧!
要写入文件,您可以使用:
file << user << std::endl;
然后简单地读给你听:
file >> user;
要继续工作,您需要一些东西:
- 用户永远不应在其密码中的任何位置输入白色-space。
- 您需要确保写入和读取始终以相同的顺序完成。
或者,您可以按照以下行创建从字符串到字符串的转换:
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);
}
然后你可以在你的 main 中读取一个数据块并简单地从中构造一个用户,或者你可以在写入之前将用户转换为字符串。这种方法的优点是您 select 分隔符并且它们在函数之间是稳定的。