gpt4 book ai didi

c++ - c中第二次读取文件时程序崩溃

转载 作者:行者123 更新时间:2023-11-28 07:33:32 25 4
gpt4 key购买 nike

使用c++文件流第二次读取文件时程序崩溃

嗨,伙计,我正在尝试构建一个允许用户输入所有数据的 Qt Gui 应用程序并使用 C++ 文件流将其写入文件。当我尝试从文件中读回所有数据时,它第一次工作正常,但是当我关闭应用程序并再次尝试读取它时,我的应用程序崩溃了。我尽力修复它,但找不到任何解决方案。任何人都可以帮助我。这是我从文件中读取数据的源代码。

void Form::OpenSlot()
{
OpenDialog = new QFileDialog();
FilePath = OpenDialog->getOpenFileName(this,"Open",AppDir,"Binary Files(*.bin)");
QString strID, strName, strSex, strSalary, strHour, strRate, strTotal;
int row = 0;
Employee *emp = NULL;

if(!FilePath.isEmpty())
{
isNew = false;
fstream fout(FilePath.toStdString().c_str(),ios::binary|ios::in);

if(fout.fail())
{
msg->setText("Error reading file.\nWrong format.");
msg->show();
fout.close();
return;
}

fout.seekg(0,ios::end);
row = (int)(fout.tellg()/sizeof(Employee));
fout.seekg(0,ios::beg);
emp = new Employee[row];
fout.read((char*)emp,row*sizeof(Employee));
fout.close();

for(int i=0;i<row;i++)
{
DisplayTable->removeRow(i);
}

for(int i=0;i<row;i++)
{
strID = QString::number((emp+i)->getID());
strName = QString::fromStdString((emp+i)->getName());
strSex = QString::fromStdString((emp+i)->getSex());
strSalary = QString::number((emp+i)->getSalary());
strHour = QString::number((emp+i)->getHour());
strRate = QString::number((emp+i)->getRate());
strTotal = QString::number((emp+i)->getTotal());

DisplayTable->insertRow(i);

DisplayTable->setItem(i,0,new QTableWidgetItem(strID));
DisplayTable->setItem(i,1,new QTableWidgetItem(strName));
DisplayTable->setItem(i,2,new QTableWidgetItem(strSex));
DisplayTable->setItem(i,3,new QTableWidgetItem(strSalary));
DisplayTable->setItem(i,4,new QTableWidgetItem(strHour));
DisplayTable->setItem(i,5,new QTableWidgetItem(strRate));
DisplayTable->setItem(i,6,new QTableWidgetItem(strTotal));
}
}
else
{
msg->setText("Can not find path");
msg->show();
}

delete []emp;

这是将数据写入文件的源代码。

void Form::SaveSlot()
{
int row = DisplayTable->rowCount();
// Write Data to file
if(!isNew)
{
fstream fin(FilePath.toStdString().c_str(),ios::binary|ios::out);
Employee *emp = new Employee[row];

for(int i=0;i<row;i++)
{
emp->setID(DisplayTable->item(i,0)->text().toInt());
emp->setName(DisplayTable->item(i,1)->text().toStdString());
emp->setSex(DisplayTable->item(i,2)->text().toStdString());
emp->setSalary(DisplayTable->item(i,3)->text().toFloat());
emp->setHour(DisplayTable->item(i,4)->text().toInt());
emp->setRate(DisplayTable->item(i,5)->text().toFloat());
emp->setTotal(DisplayTable->item(i,6)->text().toFloat());
fin.write((char*)&emp,sizeof(Employee));
}
fin.close();
}
else
{
SaveDialog = new QFileDialog();
FilePath = SaveDialog->getSaveFileName(this,"Save",AppDir,"BinaryFile(*.bin)");

if(FilePath.isEmpty())
return;

fstream fin(FilePath.toStdString().c_str(),ios::binary|ios::out);
Employee *emp = new Employee[row];

for(int i=0;i<row;i++)
{
(emp+i)->setID(DisplayTable->item(i,0)->text().toInt());
(emp+i)->setName(DisplayTable->item(i,1)->text().toStdString());
(emp+i)->setSex(DisplayTable->item(i,2)->text().toStdString());
(emp+i)->setSalary(DisplayTable->item(i,3)->text().toFloat());
(emp+i)->setHour(DisplayTable->item(i,4)->text().toInt());
(emp+i)->setRate(DisplayTable->item(i,5)->text().toFloat());
(emp+i)->setTotal(DisplayTable->item(i,6)->text().toFloat());
}

fin.write((char*)emp,row*sizeof(Employee));
fin.close();
}
}

这是 Employee 类的原型(prototype)。

class Employee
{
public:
Employee();
Employee(Employee &emp);
Employee(int id,string name,string sex,float salary,int hour,float rate,float total);
void setID(int id);
void setName(string name);
void setSex(string sex);
void setSalary(float salary);
void setHour(int hour);
void setRate(float rate);
void setTotal(float total);
int getID();
string getName();
string getSex();
float getSalary();
int getHour();
float getRate();
float getTotal();
private:
int m_id;
string m_name;
string m_sex;
float m_salary;
int m_hour;
float m_rate;
float m_total;
};

最佳答案

一个可能的问题:

fstream fout(FilePath.toStdString().c_str(),ios::binary|ios::in);

这里 FilePath.toStdString() 返回一个临时的 std::string,然后你调用 c_str() 并得到一个指向它的指针数据。然后临时字符串被销毁,你将悬空指针发送给 fstream 构造函数!你可以这样做:

string filePathStr = FilePath.toStdString();
fstream fout(filePathStr.c_str(),ios::binary|ios::in);

或者直接使用QFile。它需要一个 QString 作为文件路径。


此外,您不会在 void Form::SaveSlot() 上删除 emp:

Employee *emp = new Employee[row];

(不会导致您的崩溃,但您可能希望避免内存泄漏。)

关于c++ - c中第二次读取文件时程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17190239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com