日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对WORD文档的关键字搜索

發(fā)布時間:2023/12/10 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对WORD文档的关键字搜索 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

在網(wǎng)上找了很久,基本上對OFFICE編程都是用的OFFICE的OLE對象,但是關(guān)鍵字搜索這個問題,感覺用OLE對象顯得臃腫,而且不夠靈活,于是便寫直接讀取文件內(nèi)容進行搜索的辦法。

首先涉及的問題就是字符編碼的問題。先是在網(wǎng)上稍稍補充了一下關(guān)于UNICODE的基礎(chǔ)知識,呵呵,不過講到的東西有點多,GB、UNICODE、UTF……,也沒空細細捋順它們的關(guān)系,知道了個大概。最重要的就是了解了如何在VC下用UNICODE,呵呵。主要有:

1.為工程添加UNICODE和_UNICODE預處理選項,在VC.net中就是 項目 -> 屬性 -> c/c++ -> 預處理器 在“預處理定義”中加入這兩個宏定義(vc6中 project -> settings -> c/c++ -> general 中的 Preprocessor definitions)。

2.Include <TCHAR.h>(一般在stdafx.h中)然后把所有使用char*定義變量的地方換為LPTSTR/TCHAR*或LPCTSTR/const TCHAR*(對應(yīng)于const char*)。

3.把所有的字符串常量用_T()宏包起來,比如 TCHAR* szText = _T("我的Text")。

至于說把所有的C庫字符串操作函數(shù)也做相應(yīng)的替換,在這里我倒是沒用上多少。

下面說說我的程序。

首先,通過用ultraedit對幾個word文檔的實驗觀察,發(fā)現(xiàn)它是這樣的:WORD中如果內(nèi)容都是英文的,則用ASCII碼存儲,一旦出現(xiàn)漢字,則都用unicode存儲。

一開始所以我在掃描文件的時候,同時用兩個緩沖區(qū)保存兩種編碼方式讀到的內(nèi)容,一個是WORD型的(wUBuffer),一個是TCHAR型的(cABuffer[2]),(這里為了敘述方便,假定了緩沖區(qū)的大小)然后兩個都與待查內(nèi)容比較。

這里算法是這樣的:

1、讀入一個WORD(兩個字節(jié),低位在前,高位在后)到wUBuffer。

2、將讀到的兩個字節(jié)的低位賦給cABuffer[1]。

3、wUBuffer的高位若為0,則不處理;高位若不為0,將cABuffer左移一個元素,即aABuffer[0]=aABuffer[1],然后將wUBuffer的高位賦給aABuffer[1]。

實際上當然不會只用這么小的緩沖區(qū)。這兩個緩沖區(qū)的開辟是根據(jù)待查字符串的長度。

后來忽然想到,按照上面的方法對文件一路讀下去,是兩個字節(jié)兩個字節(jié)的讀,并未實現(xiàn)真正的逐字節(jié)掃描,于是做了如下改進:

對WORD型和TCHAR型分別開辟兩個緩沖區(qū)wUBuffer[0]、wUBuffer[1]、aABuffer[0]、aABuffer[1],下標為0的記錄掃描第偶數(shù)個字節(jié)時的內(nèi)容,下標為1的記錄第奇數(shù)個字節(jié)時的內(nèi)容,這樣在用i做循環(huán)對文件掃描時,只要wUBuffer[i % 2]和aABuffer[i % 2]就行了。而這四個緩沖區(qū)又分別是記錄讀取內(nèi)容的數(shù)組,即實際上都是二維數(shù)組。在用i做文件字節(jié)數(shù)的循環(huán)時,每次循環(huán)都把文件指針指向偏移i的位置即可。

下面是代碼。算法都實現(xiàn)在這了,應(yīng)用時可根據(jù)實際需要改進。比如這里是找到即停止,實際上可以繼續(xù)查找,把所有找到的地方都記錄下來,最后一起顯示,也可以做成像搜索引擎那樣把找到的關(guān)鍵字前后的一些內(nèi)容一塊顯示出來。

int?SearchInDoc()
{
????CString?strToFind
=_T("牧場");
????????????
????DWORD?l
=strToFind.GetLength();
????????????
????
//開辟緩沖區(qū)。unicode和ASNI各用兩個,[0]用于掃描偶數(shù)字節(jié)時的,[1]用于掃描奇數(shù)字節(jié)時
????WORD*?wUBuffer[2];
????wUBuffer[
0]=new?WORD[l+1];????//unicode?編碼時的查找緩沖區(qū)
????wUBuffer[1]=new?WORD[l+1];????//unicode?編碼時的查找緩沖區(qū)
????LPTSTR?cABuffer[2];
????cABuffer[
0]=new?TCHAR[l+1];????//與wUBuffer等長的ANSI編碼時的查找緩沖區(qū)
????cABuffer[1]=new?TCHAR[l+1];????//與wUBuffer等長的ANSI編碼時的查找緩沖區(qū)
????CString?strUBuffer[2],strABuffer[2];?//字符串緩沖區(qū),便于操作
????DWORD?i,j;
????
????
//初始化4個緩沖區(qū)
????for(i=0;i<l;i++)????
????
{
????????wUBuffer[
0][i]=0xffff;
????????cABuffer[
0][i]=(TCHAR)0xff;
????????wUBuffer[
1][i]=0xffff;
????????cABuffer[
1][i]=(TCHAR)0xff;
????}

????
//最后一個元素保存字符串結(jié)束符(實際上是賦值為結(jié)束符,但是這里好像會被當成實際的結(jié)束符,導致后面的代碼消失,故用0暫時代替)
????wUBuffer[0][l]=0;
????cABuffer[
0][l]=0;
????wUBuffer[
1][l]=0;
????cABuffer[
1][l]=0;

????HANDLE?hFile;
????hFile?
=?CreateFile(_T("f:/玩在北京.doc"),?GENERIC_READ,?FILE_SHARE_READ,?NULL,?OPEN_EXISTING,?FILE_ATTRIBUTE_NORMAL,?0);
????????
????
if(hFile?==?INVALID_HANDLE_VALUE){
????????
//TRACE("read?error:%s?%d ",?pFilePath,?GetLastError());
????????return?0;
????}


????DWORD?dwReadLen,dwFileLen
=GetFileSize(hFile,NULL);
????
????
for(i=0;i<dwFileLen;i++)????//掃描文件
????{
????????SetFilePointer(hFile,?i,?NULL,?FILE_BEGIN);??
//設(shè)置文件指針位置

????????
//兩個緩沖區(qū)都左移一個元素
????????for(j=0;j<l-1;j++)????
????????
{
????????????wUBuffer[i?
%?2][j]=wUBuffer[i?%?2][j+1];
????????????cABuffer[i?
%?2][j]=cABuffer[i?%?2][j+1];
????????}

????????????
????????
//向Unicode緩沖區(qū)最后一個元素讀入兩個字節(jié)
????????ReadFile(hFile,?&wUBuffer[i?%?2][l-1],?2,?&dwReadLen,?NULL);
????????
//將讀到的兩個字節(jié)處理:
????????
//將低位賦給cABuffer[l-1]
????????
//高位若為0,則不處理;
????????
//高位若不為0,將cABuffer再左移一個元素,賦給cABuffer[l-1]
????????
????????cABuffer[i?
%?2][l-1]=(wUBuffer[i?%?2][l-1]?&?0x00ff);
????????
if((wUBuffer[i?%?2][l-1]?&?0xff00)>0x0000)
????????
{
????????????
for(j=0;j<l-1;j++)????
????????????????cABuffer[i?
%?2][j]=cABuffer[i?%?2][j+1];
????????????cABuffer[i?
%?2][l-1]=((wUBuffer[i?%?2][l-1]?&?0xff00)>>8);
????????}


????????
????????strUBuffer[i?
%?2]=(CString)wUBuffer[i?%?2];
????????strABuffer[i?
%?2]=(CString)cABuffer[i?%?2];
????????strToFind.AnsiToOem();
????????strUBuffer[i?
%?2].AnsiToOem();
????????strABuffer[i?
%?2].AnsiToOem();

????????
if(strUBuffer[i?%?2]!=""?&&?(strUBuffer[i?%?2].Find(strToFind)>-1))
????????
{
????????????cout
<<"Found!"<<endl;
????????????cout
<<"Unicode"<<endl;

????????????delete?[]wUBuffer[
0];
????????????delete?[]wUBuffer[
1];
????????????delete?[]cABuffer[
0];
????????????delete?[]cABuffer[
1];
????????????
return?i-l;
????????}

????????
if(strABuffer[i?%?2]!=""?&&?(strABuffer[i?%?2].Find(strToFind)>-1))
????????
{
????????????cout
<<"Found!"<<endl;
????????????cout
<<"ANCI"<<endl;

????????????delete?[]wUBuffer[
0];
????????????delete?[]wUBuffer[
1];
????????????delete?[]cABuffer[
0];
????????????delete?[]cABuffer[
1];
????????????
return?i-l;
????????}

????}


????delete?[]wUBuffer[
0];
????delete?[]wUBuffer[
1];
????delete?[]cABuffer[
0];
????delete?[]cABuffer[
1];
????cout
<<"Not?Found!"<<endl;

????CloseHandle(hFile);

????
return?-1;
}
調(diào)試過程中還出了個插曲,VC莫名其妙不認識UNICODE預編譯了,調(diào)用AnsiToOem()的時候硬是說'CharToOemA' : is not a member of 'CString' ,后來又莫名其妙好了,真是FT,耗了一天的時間。詳見 http://community.csdn.net/Expert/topic/5410/5410681.xml?temp=.88081,呵呵。

總結(jié)

以上是生活随笔為你收集整理的对WORD文档的关键字搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。