最近做了一个小项目,其中在实验室测试的时候问题很少,但是在现场Bug频发,在找Bug看日志文件的时候,一些内容出现了好多次,我想统计一下这个情况出现了多少次,于是乎产生了编写一个软件,能够查询文件中的要查询内容出现的次数,甚至在文件制定行数中出现的次数。
该项目是基于Qt平台进行开发,开发时间极短,因此难免有纰漏之处,还请指出。另外本人水平有限,如有缺陷还请指出。
最后实现的界面是这样的
点击Browse…按键然后跳转至选择文件的界面,选择后,输入LineEdit会显示选择的文件。
选择文件的界面是
至于选择文件的行号有两种方案,一种是点击复选框选择开始----文件结束;另外一种是自己选择开始读取的位置和结束的位置。
另外textEdit控件输入你要查询的内容,点击输入完成Button后,便会显示重复次数。
Step1 获取文件
Qt中特有的信号和槽机制,我点击Browse…Button的时候执行响应的槽函数
void MainWindow::on_toolButton_clicked()
{
QString Myfile = QFileDialog::getOpenFileName(this, QStringLiteral("打开"), NULL, QStringLiteral("txt(*.txt);;word(*.doc;*.docx);;All (*.*)"));
qDebug()<<Myfile<<endl;
ui->lineEdit->setText(Myfile);
}
QStringLiteral(“txt(.txt);;word(.doc;.docx);;All (.*)”)代表数据类型,如果你想增加C语言文件,甚至可以写**.cpp,我查看的是日志文件.log文件,用all属性就可以。
Step2 制定特定的行
打开文件的特定行,我的想法是:打开文件,从起始处开始读取,但是我只有特定行的内容我开始获取,直到我输入的最终行结束为止。
其中流程图为
Step3 串比较并显示
利用strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。其中检测子串的代码为
int find_sub_string(const char* str1,const char* str2)
{
if(!strstr(str1,str2)) return 0;
int num = 0;
while(*str1)
{
if(strstr(str1,str2) != NULL)
num++; //判定为子字符串,次数加一
else break;
str1 = strstr(str1,str2)+1;
/*strstr返回子字符串开始位置,然后位置后移一位,重新判断*/
for(*str1; *str1 !='\0'; str1++)
{
if(*str1 == *str2)
break;
}
}
return num;
}
其中用到的类与文件是
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qfiledialog.h>
#include <QDir>
#include "QDebug"
#include <qfile.h>
#include <QMessageBox>
其中代码为
int find_sub_string(const char* str1,const char* str2)
{
if(!strstr(str1,str2)) return 0;
int num = 0;
while(*str1)
{
if(strstr(str1,str2) != NULL)
num++; //判定为子字符串,次数加一
else break;
str1 = strstr(str1,str2)+1;
/*strstr返回子字符串开始位置,然后位置后移一位,重新判断*/
for(*str1; *str1 !='\0'; str1++)
{
if(*str1 == *str2)
break;
}
}
return num;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_toolButton_clicked()
{
QString Myfile = QFileDialog::getOpenFileName(this, QStringLiteral("打开"), NULL, QStringLiteral("txt(*.txt);;word(*.doc;*.docx);;All (*.*)"));
qDebug()<<Myfile<<endl;
ui->lineEdit->setText(Myfile);
}
void MainWindow::on_pushButton_clicked()
{
bool bFlag_checkFile_Length = false;
bool bFlag_content_null = false;
int count = 0;
QString content = ui->textEdit->toPlainText(); //获取查询的内容
if(content == NULL)
bFlag_content_null = true;
QByteArray Byselect_content = content.toUtf8();
char * select_content = Byselect_content.data();
QString Myfile = ui->lineEdit->text(); //文件的内容
QString text_start = ui->lineEdit_2->text(); //起始行
QString text_end = ui->lineEdit_3->text(); //终止行
int i_text_start = text_start.toInt();
int i_text_end = text_end.toInt();
QFile file(Myfile); //打开文件
if(!file.open(QFile::ReadOnly|QFile::Text))
{
//qDebug()<<"打开失败"<<endl;
QMessageBox::warning(this,"错误","打开文件失败");
return;
}
if(ui->checkBox->isChecked() == true)
bFlag_checkFile_Length = true;
if(bFlag_checkFile_Length == false) //没有点击复选框,根据LineEdit输入的内容进行选择
{
if(i_text_start > i_text_end)
QMessageBox::warning(this,"错误","输入行数错误");
QByteArray read_temp1;
int i =1;
while((i<=i_text_end)) //根据输入的行号读取文件
{
if(i >= i_text_start)
read_temp1 += file.readLine();
else
file.readLine();
i++;
}
if(bFlag_content_null == true)
count = 0;
else
count = find_sub_string(read_temp1,select_content); //查询子串的数量
ui->lineEdit_4->setText(QString::number(count));
}
else //如果点击复选框,则从头到尾进行查询
{
QByteArray read_temp = file.readAll(); //读取整个文件
char * read_content = read_temp.data();
if(bFlag_content_null == true)
count = 0;
else
count = find_sub_string(read_temp,select_content); //查询子串的数量
ui->lineEdit_4->setText(QString::number(count));
}
file.close();
}