0

使用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 类的原型。

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;
};
4

1 回答 1

1

一个可能的问题:

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文件路径。


此外,您不会删除empvoid Form::SaveSlot()

Employee *emp = new Employee[row];

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

于 2013-06-19T11:47:34.220 回答