【发布时间】:2021-10-18 08:53:43
【问题描述】:
我有 3 个文件,main.cpp(主程序)、user.h(用户类)和 userlist.h(用于存储用户的 LinkedList 数据结构)。
我想创建一个程序来将用户存储和读取到二进制文件中。我的问题是当我运行下面的 main.cpp(第一次运行)来保存和读取文件时,它会读取并显示正常数据。但是当我运行main.cpp(第二次运行)只读取刚刚保存的文件时,它不能正常工作。
我不知道为什么会发生这种情况。我的用户类属性类型是 char*、char* 和 bool。
// main.cpp (first run)
UserList userList;
User user1("admin", "root", 1);
User user2("aaaa", "dcasf", 1);
User user3("user3", "abcd", 0);
User user4("user4", "bbbb", 0);
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
userList.saveFile("user.txt");
userList.loadFile("user.txt");
userList.display();
// main.cpp (second run)
UserList userList;
userList.loadFile("user.txt");
userList.display();
// userlist.h
#ifndef USERLIST_H
#define USERLIST_H
#include "user.h"
using namespace std;
struct UserNode{
User user;
UserNode* next = NULL;
UserNode(){}
UserNode(User user){
this->user = user;
}
UserNode(User user, UserNode* next){
this->user = user;
this->next = next;
}
};
class UserList{
public:
UserList(){
size = 0;
isEmpty = true;
head = NULL;
};
UserList(const UserList& userList);
~UserList(){
clearAll();
}
void add(User user){
if(head == NULL){
head = new UserNode();
head->user = user;
}else{
UserNode* temp = head;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = new UserNode();
temp->next->user = user;
}
}
void clearAll(){
while(head != NULL){
UserNode* temp = head;
head = head->next;
delete temp;
}
head = NULL;
}
User find(string username){
UserNode* temp = head;
while(temp != NULL){
if(temp->user.getUsername() == username){
return temp->user;
}
temp = temp->next;
}
User user;
return user;
}
bool contain(string username){
UserNode* temp = head;
while(temp != NULL){
if(temp->user.getUsername() == username){
return true;
}
temp = temp->next;
}
return false;
}
void display(){
UserNode* temp = head;
while(temp != NULL){
cout << temp->user.getUsername() << "\t" << temp->user.getPassword() << "\t" << temp->user.getIsAdmin() << endl;
temp = temp->next;
}
}
void saveFile(string filename){
ofstream output;
output.open(filename, ios::out | ios::binary);
UserNode* temp = head;
while(temp != NULL){
User user = temp->user;
output.write((char*)&user, sizeof(user));
temp = temp->next;
}
output.close();
}
void loadFile(string filename){
clearAll();
ifstream input;
input.open(filename, ios::in | ios::binary);
User user;
while(input.read((char*)&user, sizeof(user))){ // read 1 user from file
add(user);
}
input.close();
}
private:
int size;
bool isEmpty;
UserNode* head;
};
// user.h
#ifndef USER_H
#define USER_H
using namespace std;
class User{
public:
User(){}
User(char* username, char* password, bool isAdmin){
this->username = username;
this->password = password;
this->isAdmin = isAdmin;
}
~User(){}
void setUsername(char* username){
this->username = username;
}
void setPassword(char* password){
this->password = password;
}
char* getUsername(){
return username;
}
char* getPassword(){
return password;
}
bool getIsAdmin(){
return isAdmin;
}
private:
char* username;
char* password;
bool isAdmin;
};
#endif
【问题讨论】:
-
保存到文件的指针在读回时不太可能指向有效对象(除非您在写入后立即执行此操作,而这些对象仍然存在)。您需要阅读“序列化”。
-
@molbdnilo 但是我运行另一个具有相同上下文的程序,将 Box 类对象保存在文件中并在单独的运行时将其读回。它工作正常。
-
但是你的
Box类与显示的代码有什么关系?它有指针数据成员吗? -
@john 可能是因为您的
Box类只包含数字或数组,而没有指针。 (但是你不能通过观察 C++ 程序的行为来判断它是否正确 - 未定义的行为可能会出于所有错误的原因做你所期望的。) -
您的选项与已经提到的相同:1)不使用指针,或 2)实现正确的序列化。
标签: c++ file class binary fstream