QT:ASSERT failure in QList<T>::at: "index out of range"

我是一个大一Qt初学者,不怎么会调试,在做大zy的过程中碰到原本可以运行的程序经过一点点改动后无法正常运行,寻找了很多方法也没能解决问题,不久就要交了

报错:ASSERT failure in QList::at: "index out of range", file ..\5.9\mingw53_32\include/QtCore/qlist.h, line 541(应用程序输出)

gpt的回答:数组越界、迭代器失效或者使用了已经删除的对象等问题导致的

关于数组越界可能是vector使用at()函数出了些问题,自己没能找到问题,原本还是能跑的来着,我自己能记得改动只有将tablewidget里显示的列的表头改了一下

关于迭代器失效不是很理解,“在使用迭代器遍历一个容器(如 QList 或 QVector)时,如果对容器进行了插入、删除或者移动等操作,可能会导致迭代器失效。
当迭代器失效后,再通过该迭代器进行访问容器中的数据就会产生错误,进而引发程序崩溃或出现其他异常情况。”


gpt说为了避免迭代器失效,需要遵循以下几条原则:
1、尽量使用 Qt 提供的算法而不是手动写循环。Qt 的算法底层都有对迭代器失效的处理,能够更好的避免迭代器失效问题。
2、如果需要手动写循环,切勿在循环内部进行插入、删除或移动等涉及到迭代器的操作。建议先将要操作的元素记录下来,再在循环结束后一次性进行处理。
3、插入、删除或移动等涉及到迭代器的操作时,要注意返回新的迭代器,以避免使用了已经失效的迭代器。
4、在调试过程中,如果出现类似“迭代器失效”这样的异常信息,可以使用 Qt 提供的断言机制来检测错误,并在出现错误时中止程序执行,以避免后续的错误操作。


感觉我用了vector push_back()函数可能是没有遵循第二条,不知道怎么改

关于zy,是做个管理系统 ,主窗口mainwindow如下

img


本来点击登录是可以跳转出主窗口的,但是不知什么改动后出现了"index out of range”问题

img


并且原本是可以正常进行登录,对图书信息的添加,查询等操作 然后我打算添加一个清空数据的功能,但清空数据后会丢失数据需要重新录入 于是我写了一个清空“booklist.csv”后恢复样例数据的代码

img

关于使用到vector容器的代码块在下面,由于是边写边学,代码排版混乱,结构也混乱

img

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTableWidget>
#include <QPushButton>
#include <QTextStream>
#include <QFile>
#include <QDateTime>
#include <QString>
#include <QMessageBox>
#include<QDialog>
#include "logindialog.h"
#include<QDebug>
#include <QGraphicsDropShadowEffect>


MainWindow::MainWindow(QWidget *parent, std::string path)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , filePath(path) // 将path传递给新添加的成员变量
    , fileStorage(path) // 把path传递给FileStorage的构造函数
{

//    updateBookListTable();

    ui->setupUi(this);

//    this->setStyleSheet("background-color: pink;");
    this->setStyleSheet("background-color: white;");


    // 创建状态栏
       QStatusBar *statusBar = new QStatusBar(this);
       setStatusBar(statusBar);





    showLoginDialog();

    ui->treeWidget->clear();
    ui->treeWidget->setColumnCount(1);
    QStringList l;
    l<<"图书列表";

    QTreeWidgetItem *pf=new QTreeWidgetItem(ui->treeWidget,l);
    ui->treeWidget->addTopLevelItem(pf);

    l.clear();
    l<<"入库记录";
    QTreeWidgetItem *p1=new QTreeWidgetItem(ui->treeWidget,l);


    l.clear();
    l<<"出库记录";

    QTreeWidgetItem *p2=new QTreeWidgetItem(ui->treeWidget,l);

    pf->addChild(p1);
    pf->addChild(p2);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_2_clicked()//_______修改
{




}


void MainWindow::on_pushButton_4_clicked()//查询
{
    QString queryStr = ui->queryEdit->text();
    if(queryStr.isEmpty()){

     QMessageBox::warning(this, "Error", "输入不能为空!");
    }
    else{
        QTableWidget *tableWidget = ui->tableWidget;
        tableWidget->clear();
        tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数"<< "入库日期"  << "数量" << "单价");


        int index=0;
        for(int i=0; i<inventory.getBook().size(); i++){
         Book book = inventory.getBook().at(i);
         if(ui->queryEdit->text()==book.getAuthor()||ui->queryEdit->text()==book.getTitle())
         {
             index++;
         }
        }//计数 从而确定rowCount

        if(index==0){
            QMessageBox:: information(nullptr , "信息" , "图书不存在!");

        }
        else{
            int rowCount =index;
            int columnCount = 7;
            tableWidget->setRowCount(rowCount);
            tableWidget->setColumnCount(columnCount);

            for(int i=0,j=0; i<inventory.getBook().size(); i++){
             Book book = inventory.getBook().at(i);
             if(ui->queryEdit->text()==book.getAuthor()||ui->queryEdit->text()==book.getTitle())
             {
                 QTableWidgetItem *titleItem = new QTableWidgetItem(book.getTitle());
                 QTableWidgetItem *authorItem = new QTableWidgetItem(book.getAuthor());
                 QTableWidgetItem *publisherItem = new QTableWidgetItem(book.getPublisher());
                 QTableWidgetItem *pagesItem = new QTableWidgetItem(QString::number(book.getPages()));
                 QTableWidgetItem *dateItem = new QTableWidgetItem(book.getStockDate());
                 QTableWidgetItem *quantityItem = new QTableWidgetItem(QString::number(book.getQuantity()));
                 QTableWidgetItem *priceItem = new QTableWidgetItem(QString::number(book.getPrice()));

                 tableWidget->setItem(j, 0, titleItem);
                 tableWidget->setItem(j, 1, authorItem);
                 tableWidget->setItem(j, 2, publisherItem);
                 tableWidget->setItem(j, 3, pagesItem);
                 tableWidget->setItem(j, 4, dateItem);
                 tableWidget->setItem(j, 5, quantityItem);
                 tableWidget->setItem(j, 6, priceItem);

                 j++;
             }
            }

        }


    }


}

void MainWindow::updateBookListTable(){
    qDebug()<<"updateBookListTable";
    inventory.books.clear();

    QFile file("booklist.csv");
    if(file.open(QFile::ReadOnly | QFile::Text)){
       QTextStream in(&file);
       while(!in.atEnd()){
           QString line = in.readLine();
           QStringList fields = line.split(",");
           QString title = fields.at(0);
           QString author = fields.at(1);
           QString publisher = fields.at(2);
           QString pages = fields.at(3);
           QString dateTimeStr = fields.at(4);
           QString quantity = fields.at(5);
           QString price = fields.at(6);
           int pagesInt=pages.toInt();
           int quantityInt=quantity.toInt();
           double priceDouble=price.toDouble();
           // TODO: 创建Book对象,并添加到列表中
            Book book(title, author, publisher, pagesInt, dateTimeStr, quantityInt, priceDouble);
            inventory.books.push_back(book);

       }
       file.close();
    }


    QTableWidget *tableWidget = ui->tableWidget;
    tableWidget->clear();
    int rowCount =inventory.getBook().size();
    qDebug()<<"inventory.getBook().size()="<<inventory.getBook().size();
    int columnCount = 7;

    tableWidget->setRowCount(rowCount);
    tableWidget->setColumnCount(columnCount);

    tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数/页"<< "入库日期"  << "数量/本" << "单价/元");

    for(int i=0; i<inventory.getBook().size(); i++){
        Book book = inventory.getBook().at(i);
        QTableWidgetItem *titleItem = new QTableWidgetItem(book.getTitle());
        QTableWidgetItem *authorItem = new QTableWidgetItem(book.getAuthor());
        QTableWidgetItem *publisherItem = new QTableWidgetItem(book.getPublisher());
        QTableWidgetItem *pagesItem = new QTableWidgetItem(QString::number(book.getPages()));
        QTableWidgetItem *dateItem = new QTableWidgetItem(book.getStockDate());
        QTableWidgetItem *quantityItem = new QTableWidgetItem(QString::number(book.getQuantity()));
        QTableWidgetItem *priceItem = new QTableWidgetItem(QString::number(book.getPrice()));

        tableWidget->setItem(i, 0, titleItem);
        tableWidget->setItem(i, 1, authorItem);
        tableWidget->setItem(i, 2, publisherItem);
        tableWidget->setItem(i, 3, pagesItem);
        tableWidget->setItem(i, 4, dateItem);
        tableWidget->setItem(i, 5, quantityItem);
        tableWidget->setItem(i, 6, priceItem);


    }
    // 补全空白行
    int blankRowCount = tableWidget->rowCount() - rowCount;
    for(int i=0; i<blankRowCount; i++){
        tableWidget->removeRow(rowCount);
}

}

void MainWindow::showLoginDialog()
{

    if (dialog.exec() == QDialog::Accepted) {
        // 登录成功
        statusBar()->showMessage(tr("登录成功"), 2000);

        inventory.books.clear();

        QFile file("booklist.csv");
        if(file.open(QFile::ReadOnly | QFile::Text)){
           QTextStream in(&file);
           while(!in.atEnd()){
               QString line = in.readLine();
               QStringList fields = line.split(",");
               QString title = fields.at(0);
               QString author = fields.at(1);
               QString publisher = fields.at(2);
               QString pages = fields.at(3);
               QString dateTimeStr = fields.at(4);
               QString quantity = fields.at(5);
               QString price = fields.at(6);
                int pagesInt=pages.toInt();
                int quantityInt=quantity.toInt();
                double priceDouble=price.toDouble();
               // TODO: 创建Book对象,并添加到列表中
                Book book(title, author, publisher, pagesInt, dateTimeStr, quantityInt, priceDouble);
                inventory.books.push_back(book);

           }
           file.close();
        }
        else{
           // 处理打开失败的情况
//                QMessageBox::critical(this, "Error", QString("Failed to open file %1").arg(QString::fromStdString(path)));
                QMessageBox::warning(this, "Error", "源文件打开失败!");

        }
        QTableWidget *tableWidget = ui->tableWidget;
    tableWidget->clear();
    int rowCount =inventory.getBook().size();
    int columnCount = 7;
    tableWidget->setRowCount(rowCount);
    tableWidget->setColumnCount(columnCount);

    tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数"<< "入库日期"  << "数量" << "单价");
//    tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数/页"<< "入库日期"  << "数量/本" << "单价/元");

    for(int i=0; i<inventory.getBook().size(); i++){
     Book book = inventory.getBook().at(i);
     QTableWidgetItem *titleItem = new QTableWidgetItem(book.getTitle());
     QTableWidgetItem *authorItem = new QTableWidgetItem(book.getAuthor());
     QTableWidgetItem *publisherItem = new QTableWidgetItem(book.getPublisher());
     QTableWidgetItem *pagesItem = new QTableWidgetItem(QString::number(book.getPages()));
     QTableWidgetItem *dateItem = new QTableWidgetItem(book.getStockDate());
     QTableWidgetItem *quantityItem = new QTableWidgetItem(QString::number(book.getQuantity()));
     QTableWidgetItem *priceItem = new QTableWidgetItem(QString::number(book.getPrice()));

     tableWidget->setItem(i, 0, titleItem);
     tableWidget->setItem(i, 1, authorItem);
     tableWidget->setItem(i, 2, publisherItem);
     tableWidget->setItem(i, 3, pagesItem);
     tableWidget->setItem(i, 4, dateItem);
     tableWidget->setItem(i, 5, quantityItem);
     tableWidget->setItem(i, 6, priceItem);
//     tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数/页"<< "入库日期"  << "数量/本" << "单价/元");
     tableWidget->setHorizontalHeaderLabels(QStringList() << "图书名称"<<"作者"<<"出版社"<<"页数"<< "入库日期"  << "数量" << "单价");

    }
    // 补全空白行
    int blankRowCount = tableWidget->rowCount() - rowCount;
    for(int i=0; i<blankRowCount; i++){
        tableWidget->removeRow(rowCount);
    }
    this->show();

    }
    else {
        // 取消登录或登录失败
        statusBar()->showMessage(tr("登录失败"), 2000);

    }

}


void MainWindow::on_add_book_button_clicked()
{
    inventory.books.clear();
    QFile file("booklist.csv");
    if(file.open(QFile::ReadOnly | QFile::Text)){
       QTextStream in(&file);
       while(!in.atEnd()){
           QString line = in.readLine();
           QStringList fields = line.split(",");
           QString title = fields.at(0);
           QString author = fields.at(1);
           QString publisher = fields.at(2);
           QString pages = fields.at(3);
           QString dateTimeStr = fields.at(4);
           QString quantity = fields.at(5);
           QString price = fields.at(6);
            int pagesInt=pages.toInt();
            int quantityInt=quantity.toInt();
            double priceDouble=price.toDouble();
           // TODO: 创建Book对象,并添加到列表中
            Book book(title, author, publisher, pagesInt, dateTimeStr, quantityInt, priceDouble);
            inventory.books.push_back(book);

       }
       file.close();}
    else{
       // 处理打开失败的情况
        QMessageBox::warning(this, "Error", "源文件打开失败!");

    }
    dlg_add.exec();
    updateBookListTable();


}


void MainWindow::on_pushButton_clicked()//退出
{
    exit(0);
}



void MainWindow::on_pushButton_5_clicked()//查询后 重新显示全部
{
    updateBookListTable();
}


void MainWindow::on_pushButton_6_clicked()//清空
{
    QFile qfile("booklist.csv");
        if(qfile.open(QIODevice::WriteOnly|QIODevice::Text)){
            QTextStream out(&qfile);
            out.setCodec("UTF-8"); // 设置编码格式
            qfile.resize(0); // 清空文件内容
            qfile.close();
        }
        updateBookListTable();

}



#include "dlg_add.h"
#include "ui_dlg_add.h"
#include <QDateTime>
#include <QString>
#include "book.h"
#include <QFile>
#include<QTextStream>
#include "inventory.h"
#include <QMessageBox>
#include<QDebug>
//#include "mainwindow.h"



Dlg_add::Dlg_add(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dlg_add)
{
    ui->setupUi(this);

}

Dlg_add::~Dlg_add()
{
    delete ui;
}
//void Dlg_add::on_saveButton_clicked()
//{

//}

void Dlg_add::on_pushButton_2_clicked()
{
    this->reject();
}

void Dlg_add::on_saveButton_clicked()
{
    QString title = ui->titleEdit->text();
    QString author = ui->authorEdit->text();
    QString publisher = ui->publisherEdit->text();
    QString pages = ui->pagesEdit->text();

    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString currentDateTimeStr = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");

    QString quantity = ui->quantityEdit->text();
    QString price = ui->priceEdit->text();

//    bool ok1, ok2, ok3;
//    int pagesInt = pages.toInt(&ok1);
//    int quantityInt = quantity.toInt(&ok2);
//    double priceDouble = price.toDouble(&ok3);
//    if(ok1 && ok2 && ok3){
//       Book book(title, author, publisher, pagesInt, currentDateTimeStr, quantityInt, priceDouble);
//       //添加图书信息到数据文件等操作
//    }else{
//       //处理转换失败的情况
//    QMessageBox::warning(this, "Error", "Input format error");
//    }


    // 将图书信息添加到列表中___________________________________待定
//    m_bookList.append(book);
    vector<Book> booklist;
    //创建辅助图书列表读取文件
    QFile file1("booklist.csv");
    if(file1.open(QFile::ReadOnly | QFile::Text)){
       QTextStream in(&file1);
       while(!in.atEnd()){
           QString line = in.readLine();
           QStringList fields = line.split(",");
           QString title = fields.at(0);
           QString author = fields.at(1);
           QString publisher = fields.at(2);
           QString pages = fields.at(3);
           QString dateTimeStr = fields.at(4);
           QString quantity = fields.at(5);
           QString price = fields.at(6);
           int pagesInt=pages.toInt();
           int quantityInt=quantity.toInt();
           double priceDouble=price.toDouble();
           // TODO: 创建Book对象,并添加到列表中
            Book book(title, author, publisher, pagesInt, dateTimeStr, quantityInt, priceDouble);
            booklist.push_back(book);

       }
       file1.close();
    }

    int index=0;
    int pagesInt = pages.toInt();
    int quantityInt = quantity.toInt();
    double priceDouble = price.toDouble();
    for(int i=0; i<booklist.size(); i++){
     Book book = booklist.at(i);
     if(author==book.getAuthor() &&  title==book.getTitle()&&
        pagesInt==book.getPages()   &&  publisher==book.getPublisher()&&
       priceDouble==book.getPrice())
         //图书已存在 只添加数量
     {
         index=1;
         booklist.at(i).quantity+=quantityInt;
         booklist.at(i).stockDate=currentDateTimeStr;


     }
    }
        if(index)//删除文件 重写
        {
            //清空“booklis.csv”
            //将booklist导入“booklis.csv”
            QFile qfile("booklist.csv");
                if(qfile.open(QIODevice::WriteOnly|QIODevice::Text)){
                    QTextStream out(&qfile);
                    out.setCodec("UTF-8"); // 设置编码格式
                    qfile.resize(0); // 清空文件内容
                    qfile.close();
                }

            QFile afile("booklist.csv");
            if(!afile.exists()){
                   //文件不存在,创建文件
                   if (afile.open(QIODevice::WriteOnly|QIODevice::Text)) {
                       qDebug() << "文件创建成功";
                   } else {
                       qDebug() << "文件创建失败";
                   }
               }
            if (afile.open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
                QTextStream out(&afile);
                out.setCodec("UTF-8"); // 设置编码格式
                for(int i=0; i<booklist.size(); i++){
                 Book book = booklist.at(i);
                 QString b_title = book.getTitle();
                 QString b_author = book.getAuthor();
                 QString b_publisher = book.getPublisher();
                 QString b_pages = QString::number(book.getPages()); // 将整数类型的页数转换为字符串类型
//                 QString b_currentDateTimeStr = book.getStockDate().toString(Qt::ISODate); // 将日期时间类型转换为字符串类型
                 QString b_quantity = QString::number(book.getQuantity()); // 将整数类型的数量转换为字符串类型
                 QString b_price = QString::number(book.getPrice(), 'f', 2); // 将 double 类型的价格转换为字符串类型并保留两位小数
                out << b_title << "," << book.getAuthor() << "," << b_publisher << "," <<b_pages  << ","
                    <<book.getStockDate() << "," <<b_quantity << "," <<b_price<< endl;
                }
                afile.close();
            }


        }

        else
        { // 保存图书信息到 CSV 文件中 追加式写文件
        QFile file("booklist.csv");
        if(!file.exists()){
               //文件不存在,创建文件
               if (file.open(QIODevice::WriteOnly|QIODevice::Text)) {
                   qDebug() << "文件创建成功";
    //               file.close();
               } else {
                   qDebug() << "文件创建失败";
               }
           }
        if (file.open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
            QTextStream out(&file);
            out.setCodec("UTF-8"); // 设置编码格式
            out << title << "," << author << "," << publisher << "," <<pages << "," <<currentDateTimeStr << "," <<quantity << "," <<price<< endl;
            file.close();
        }

            // 保存图书信息到 CSV 文件中(2)
            QFile sfile("purchase.csv");
            if(!sfile.exists()){
                   //文件不存在,创建文件
                   if (sfile.open(QIODevice::WriteOnly|QIODevice::Text)) {
                       qDebug() << "文件创建成功";
        //               file.close();
                   } else {
                       qDebug() << "文件创建失败";
                   }
               }
            if (sfile.open(QFile::WriteOnly | QFile::Text | QFile::Append)) {
                QTextStream out(&sfile);
                out.setCodec("UTF-8"); // 设置编码格式
                out << title << "," << author << "," << publisher << "," <<pages << "," <<currentDateTimeStr << "," <<quantity << "," <<price<< endl;
                sfile.close();
            }

    }


        // 清空输入框中的内容
        ui->titleEdit->clear();
        ui->authorEdit->clear();
        ui->publisherEdit->clear();
        ui->pagesEdit->clear();
        ui->quantityEdit->clear();
        ui->priceEdit->clear();

        QMessageBox:: information(nullptr , "信息" , "存储成功");

            close();

}