问题描述
我每次接收数据时都试图在文件中添加一行,如果行数超过 10 行,则创建新文件来存储数据,直到创建 5 个文件,但我遇到了一个问题,那就是应用程序将在第 56 行崩溃:QTextStream stream(current_record_file);
,代码为:
mainwindow.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++;
}
}
}
mainwindow.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
解决方法
正如 chehrlic 的评论所述,您正在访问一个(悬空)指针,该指针指向已超出范围的对象。
存在两种解决方案:
- 在每次写入时重新打开文件(可能与
QFile::Truncate
不兼容且效率较低) - 使用
QFile current_record_file
作为成员,而不是QFile* current_record_file
。在我看来,这似乎是最好的方法。
谢谢大家的回复,我尝试了m7913d的第二种方案,现在可以创建多个QFile了!神奇的一点是,当你关闭最后一个 QFile current_record_file,并通过 current_record_file.setFileName(record_file_name);
重置其文件名后,programm 将帮助我们自动创建新文件。新的可用代码是:
#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(¤t_record_file);
stream << "START\r\n";
msg_line_count = 0;
}else if(msg_line_count == 10){
//write footer to privious file
QTextStream stream(¤t_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(¤t_record_file);
stream2 << "START\r\n";
msg_line_count = 0;
}else{
//write the main body
QTextStream stream(¤t_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