【问题标题】:How to write data to mutiple QFiles如何将数据写入多个文件
【发布时间】:2021-07-09 15:20:31
【问题描述】:

我每次接收数据时都尝试在文件中添加一行,如果行数超过 10 行,则创建新文件来存储数据,直到创建 5 个文件,但我遇到了一个问题,那就是应用程序将在第 56 行崩溃:QTextStream stream(current_record_file); ,代码为:

ma​​inwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    simulateReceiveData();
}

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

void MainWindow::simulateReceiveData()
{
    while(file_count < 5){
        qDebug()<<"on recording ...";
        if(file_count == 1 && msg_line_count == -1){
            //create the very first new file
            record_file_name_prefix = "D:/Project/MessageRecording";
            QString record_file_name = record_file_name_prefix + "(1).asc";
            qDebug()<<"record_file_name is"<<record_file_name;
            QFile file(record_file_name);
            if (!file.open(QFile::WriteOnly | QFile::Truncate)){
                qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
                return;
            }

            //write the header
            current_record_file = &file;
            QTextStream stream(current_record_file);
            stream << "START\r\n";
            msg_line_count = 0;

        }else if(msg_line_count == 10){
            //write footer to privious file
            QTextStream stream(current_record_file);
            stream << "END";
            stream.flush();
            current_record_file->close();

            //create next new file
            file_count++;
            QString record_file_name = record_file_name_prefix + QString("(%1).%2").arg(file_count).arg("asc");
            QFile file(record_file_name);
            if (!file.open(QFile::WriteOnly | QFile::Truncate))
                return;
            current_record_file = &file;  //redirect to the new created file
            msg_line_count = 0;
        }else{
            //write the main body
            QTextStream stream(current_record_file); // CRASH HERE !
            stream <<"0.0000 0 Rx 00 00 00 00 00 00 00 00\r\n";
            msg_line_count++;
        }
    }
}

ma​​inwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFile>
#include <QDateTime>
#include <QTextStream>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    void simulateReceiveData();
    int file_count = 1;//number of files
    int msg_line_count = -1;//number of lines in one file
    QString record_file_name_prefix;
    QFile* current_record_file = nullptr;//point to currently written file
};
#endif // MAINWINDOW_H

【问题讨论】:

  • 使用调试器查看应用程序的状态,并使用该信息确定发生了什么问题。很可能您在某处有一些未定义的行为(如悬空指针/引用取消引用)。
  • Basic c++ - 您的 QFile 实例超出范围,因此您有一个悬空指针
  • 我在Wikipedia上查了悬空指针,确实是这样的问题,所以我需要让所有5个QFile实例都活着,我明天会研究如何制作~

标签: qt qtextstream


【解决方案1】:

正如 chehrlic 的评论所述,您正在访问一个(悬空)指针,该指针指向一个超出范围的对象。

存在两种解决方案:

  1. 每次写入时重新打开文件(可能与QFile::Truncate 不兼容且效率较低)
  2. 使用QFile current_record_file 作为成员,而不是QFile* current_record_file。在我看来,这是最好的方法。

【讨论】:

    【解决方案2】:

    感谢大家的回复,我试过m7913d的第二种方案,现在可以创建多个QFile了!神奇的一点是在你关闭最后一个QFile current_record_file,并用current_record_file.setFileName(record_file_name);重置它的文件名后,程序会自动帮助我们创建新文件。新的可行代码是:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QThread>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        simulateReceiveData();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::simulateReceiveData()
    {
        while(file_count < 5){
            qDebug()<<"on recording ...";
    
            if(file_count == 1 && msg_line_count == -1){
                //create the very first new file
                record_file_name_prefix = "D:/Project/MessageRecording";
                QString record_file_name = record_file_name_prefix + QString::number(file_count) + ".asc";
                current_record_file.setFileName(record_file_name);
                if (!current_record_file.open(QFile::WriteOnly | QFile::Truncate)){
                    qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
                    return;
                }
    
                //write the header
                QTextStream stream(&current_record_file);
                stream << "START\r\n";
                msg_line_count = 0;
    
            }else if(msg_line_count == 10){
                //write footer to privious file
                QTextStream stream(&current_record_file);
                stream << "END";
                stream.flush();
                current_record_file.close();
    
                file_count++;
                QString record_file_name = record_file_name_prefix + QString::number(file_count) +  ".asc";
                qDebug()<<"new record file is"<<record_file_name;
                current_record_file.setFileName(record_file_name);
                if (!current_record_file.open(QFile::WriteOnly | QFile::Truncate)){
                    qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
                    return;
                }
    
                QTextStream stream2(&current_record_file);
                stream2 << "START\r\n";
                msg_line_count = 0;
    
            }else{
                //write the main body
                QTextStream stream(&current_record_file); // CRASH HERE !
                stream <<file_count<<" 0.0000 0 Rx 00 00 00 00 00 00 00 00\r\n";
                msg_line_count++;
                QThread::sleep(1);
            }
        }
    }
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QFile>
    #include <QDateTime>
    #include <QTextStream>
    #include <QDebug>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
        void simulateReceiveData();
        int file_count = 1;//number of files
        int msg_line_count = -1;//number of lines in one file
        QString record_file_name_prefix;
        QFile current_record_file;
    };
    #endif // MAINWINDOW_H
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多