我的想法真的用完了。我只想从一个二进制文件中读取和写入我创建的类。
int ClientData::readClientDat(ClientData * client_block)
{
int clientData_SIZE;
ifstream inClients;
inClients.open("D:\Programming\Qt\bookstore instances\bookstore_system\data\clients.dat", ios::binary);
clientData_SIZE = static_cast<int>(inClients.tellg());
client_block = new ClientData [clientData_SIZE+1];
if (inClients.is_open())
{
for(int i = 0; i <clientData_SIZE; i++)
{
// inClients.read((char *)&client_block[i].user, sizeof(client_block[i].user));
// inClients.read((char *)&client_block[i].pass, sizeof(client_block[i].pass));
// inClients.read((char *)&client_block[i].mail, sizeof(client_block[i].mail));
// inClients.read((char *)&client_block[i].id, sizeof(client_block[i].id));
inClients.read((char *)(&client_block[i]), sizeof(ClientData));
}
inClients.close();
}
return clientData_SIZE;
}
由于某种原因,它读不正确,我猜我的书写功能出了问题
void ClientData::insertNewClient(ClientData newUser)
{
ofstream outClients;
outClients.open("D:\Programming\Qt\bookstore instances\bookstore_system\data\clients.dat", ios::binary | ios::app); // write the new client's data in the database.
int clientData_SIZE = outClients.tellp();
newUser.id = (clientData_SIZE) + 1;
// ClientData * client_block;
// client_block[clientData_SIZE] = newUser;
outClients.write((char *)(&newUser), sizeof(ClientData));
outClients.close(); //-----------------------------------------closes file.
}
我该怎么办?
这是我的班级
class ClientData
{
public:
ClientData();
int readClientDat(ClientData * client_block);
ClientData enter_activeUser(QString QUser, QString QPass, QString QMail);
bool isAdmin(ClientData user);
bool userExists(ClientData newClient);
int isClient(ClientData &user);
void insertNewClient(ClientData newUser);
private:
char user[32];
char pass[32];
char mail[32];
int id;
};
好吧,这篇文章会很重要,但我希望我至少能解决所有的主要问题。
首先:你不应该把整个类写到一个文件中并期望它能工作,这通常适用于POD类型,但不适用于C++类。
第二:读取函数按值接收指针,然后泄漏分配的内存。
现在,让我们从读取功能开始:
clientData_SIZE = static_cast<int>(inClients.tellg());
这显然会返回零,因为您处于文件的开头。您需要seek
到文件的末尾,然后才能获得指针的位置(请参阅文章末尾的示例(。
此代码:
inClients.read((char *)(&client_block[i]), sizeof(ClientData));
不要指望它能起作用,即使你正确地确定了文件的大小和迭代次数。类不是POD类型,它们有构造函数、析构函数、方法,可能还有vtable。无法记忆的东西。
现在有了写功能:
int clientData_SIZE = outClients.tellp();
这将是文件中的字节数,而不是客户端数!如果您想要客户端的数量,您应该除以sizeof(ClientData((,但是,正如我之前所说,不建议将类写入文件。
现在出现了序列化的概念:序列化允许将数据从一个点传输到另一个点,就像它是一个简单的副本一样。您需要编写代码来支持这一点。
您可以实现函数write(ostream&)
和read(istream&)
,也可以重载流运算符:
class ClientData {
// ...
friend ostream& operator<<(ostream &out, const ClientData &c);
friend istream& operator>>(istream &in, ClientData &c);
};
// ok this is a hack, but it works as an example
#define CLIENT_DATA_SIZE (32+32+32+4)
ostream& operator<<(ostream& os, const ClientData& cd) {
os.write(cd.user, sizeof(user));
os.write(cd.pass, sizeof(pass));
os.write(cd.mail, sizeof(mail));
os.write(&cd.id, sizeof(id))
return os;
}
istream& operator>>(istream &in, ClientData &cd) {
in.read(cd.user, sizeof(user));
in.read(cd.pass, sizeof(pass));
in.read(cd.mail, sizeof(mail));
in.read(&cd.id, sizeof(id));
return in;
}
然后读取功能应该是这样的:
// note this changed to pointer to pointer (you can also pass the pointer by reference)
int ClientData::readClientDat(ClientData **client_block)
{
int clientData_SIZE;
ifstream inClients;
inClients.open("D:\Programming\Qt\bookstore instances\bookstore_system\data\clients.dat", ios::binary);
if (inClients.is_open())
{
inClients.seek(0, inClients.end);
clientData_SIZE = static_cast<int>(inClients.tellg()) / CLIENT_DATA_SIZE;
// dont forget to relese the pointer (with delete[]) when finished
client_block = new ClientData [clientData_SIZE];
for(int i = 0; i <clientData_SIZE; i++)
{
clientData_SIZE >> client_block[i];
}
inClients.close();
}
return clientData_SIZE;
}
以及写入功能:
void ClientData::insertNewClient(ClientData newUser)
{
ofstream outClients;
outClients.open("D:\Programming\Qt\bookstore instances\bookstore_system\data\clients.dat", ios::binary | ios::app); // write the new client's data in the database.
int clientData_SIZE = outClients.tellp() / CLIENT_DATA_SIZE;
newUser.id = (clientData_SIZE) + 1;
outClientes << newUser;
outClients.close(); //-----------------------------------------closes file.
}
注意,我没有检查错误,你可能想检查读、写和打开是否返回正常。