編譯環境:QT5(創建時選擇的是widget)
主要是將一個大文件拆成多個小文件,這樣子就能夠大大地節省了搜索的時間。
主要代碼如下:
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(600,400);
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QTextCodec> //ASCII轉UTF-8
#include <QCursor>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("酒店入住記錄查詢");
label1=new QLabel();
label1->setText("文件大小1.27GB\n記錄數20151574");
label2=new QLabel();
label2->setText("請輸入要查詢的姓名:");
btn1=new QPushButton();
btn1->setText("查詢");
edit1=new QLineEdit();
text1=new QTextBrowser();
QHBoxLayout *layout1=new QHBoxLayout();
layout1->addWidget(label2);
layout1->addWidget(edit1);
layout1->addWidget(btn1);
QVBoxLayout *layout2=new QVBoxLayout(this);
layout2->addWidget(label1);
layout2->addLayout(layout1);
layout2->addWidget(text1);
connect(btn1,SIGNAL(clicked()),this,SLOT(on_clicked())); //將btn1與on_clicked()關聯
}
Widget::~Widget()
{
}
void Widget::select(int n) //n==1代表查詢原始數據文件 n==2查詢索引文件
{
clock_t start=clock(); //執行效率計時開始
QTextCodec *codec=QTextCodec::codecForName("GBK");
char key[2048]={0};
char content[2048]={0};
const char*s= codec->fromUnicode(edit1->text().trimmed()).data();//將edit1中的內容從QString轉化爲const char*
strcpy(key,s);
if(strlen(key)<4)
{
QMessageBox::information(this,"錯誤","輸入不正確,請重新輸入");
return;
}
key[strlen(key)]=',';
char path[1024]={0};
if(n == 1)
strcpy(path,"D:/Documents/code/hotel/db/kaifang_noBomb.txt");
else if(n ==2)
{
int index=((unsigned char)key[0]+(unsigned char)key[1]+(unsigned char)key[2]+(unsigned char)key[3])%256;
sprintf(path,"D:/Documents/code/hotel/db/index/%d.db",index);
}
FILE *p=fopen(path,"r");
if(!p)
{
QString str=path;
str+="打開失敗";
QMessageBox::information(this,"錯誤",str);
return ;
}
this->setCursor(Qt::WaitCursor);
text1->clear();
unsigned int count=0; //計數器
while(!feof(p))
{
memset(content,0,sizeof(content));
fgets(content,sizeof(content),p);
if(content[strlen(content)-1] == '\n')
content[strlen(content)-1]=0;
if(strncmp(content,key,strlen(key))== 0)
{
text1->append(codec->toUnicode(content));
count++;
}
}
clock_t end=clock();
this->setCursor(Qt::ArrowCursor);
fclose(p);
QString res="找到"+QString::number(count)+"條記錄,用時"+QString::number(end-start)+"毫秒";
QMessageBox::information(this,"完成",res);
}
void Widget::create_index()
{
clock_t start=clock();
char path[1024]={0};
strcpy(path,"D:/Documents/code/hotel/db/kaifang_noBomb.txt");
FILE *p=fopen(path,"r");
if(!p)
{
QString str=path;
str+="打開失敗";
QMessageBox::information(this,"錯誤",str);
return ;
}
FILE *pt[256]={NULL};
//建立256個索引文件並打開
for(int i=0;i<256;i++)
{
memset(path,0,sizeof(path));
sprintf(path,"D:/Documents/code/hotel/db/index/%d.db",i);
pt[i]=fopen(path,"w");
}
this->setCursor(Qt::WaitCursor);
char buf[1024]={0};
int index=0; //索引值
while(!feof(p))
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),p);
if(buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1]=0;
//根據關鍵字求索引鍵值
index=((unsigned char)buf[0]+(unsigned char)buf[1]+(unsigned char)buf[2]+(unsigned char)buf[3])%256;
fprintf(pt[index],"%s\n",buf);
}
fclose(p);
for(int i=0;i<256;i++)
{
fclose(pt[i]);
}
clock_t end=clock();
this->setCursor(Qt::ArrowCursor);
QString res="用時"+QString::number(end-start)+"毫秒";
QMessageBox::information(this,"完成",res);
}
void Widget::on_clicked()
{
//QMessageBox::information(this,"提示","按鈕被按了");
select(2);
}
效果圖: