摘要:字?jǐn)?shù)統(tǒng)計(jì)是文檔處理中經(jīng)常要用到的功能,這其中要包括英文單詞、數(shù)字和中文等,而且又要和全角或半角的標(biāo)點(diǎn)符號(hào)進(jìn)行區(qū)分,故此在中英文混合文件中進(jìn)行準(zhǔn)確的字?jǐn)?shù)統(tǒng)計(jì)也是有一定難度的。這里提出了一種較好的字?jǐn)?shù)統(tǒng)計(jì)的方法,可以很好的區(qū)分出英文單詞、數(shù)字和漢字,并以C語言為工具進(jìn)行了實(shí)現(xiàn)。
關(guān)鍵詞:字?jǐn)?shù)統(tǒng)計(jì);漢字;標(biāo)點(diǎn)符號(hào);C語言;實(shí)現(xiàn)
中圖分類號(hào):TP312文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)34-2028-02
Word Statistics Based on C
TANG Xiao-le
(Dept. of Computer, Henan Industry Trade Vocational College, Zhengzhou 450012, China)
Abstract: Word statistics is a kind of function which is usually used and it includes English words, digits and Chinese characters, what’s more, it must discriminate single byte punctuation marks from double byte punctuation marks. So it is of some difficulty when counting words accurately in compound files. A method is presented to count word which can separate English words, digits and Chinese words and is realized based on C language.
Key words:word statistics; Chinese character; punctuation marks; C language; realization
1 引言
ASCII是用來表示英文字符的一種編碼規(guī)范,每個(gè)ASCII字符占用1個(gè)字節(jié)(8bits)。因此,ASCII編碼可以表示的最大字符數(shù)是256,其實(shí)英文字符并沒有那么多,一般只用前128個(gè)(最高位為0),其中包括了控制字符、數(shù)字、大小寫字母和其他一些符號(hào)。
中文的文字編碼規(guī)范叫做“GB2312-80”,它是和ASCII兼容的一種編碼規(guī)范,其實(shí)就是把一個(gè)中文字符用兩個(gè)擴(kuò)展ASCII字符來表示。我們必須判斷一個(gè)ASCII碼是否擴(kuò)展,以及它的下一個(gè)ASCII是否擴(kuò)展,然后才“猜”那可能是一個(gè)中文字符。而由于漢字和全角字符都是用兩個(gè)擴(kuò)展ASCII字符來表示,所以還需進(jìn)一步加以區(qū)分。這樣統(tǒng)計(jì)中英文混合文件中的字?jǐn)?shù),也是比較復(fù)雜的,有些軟件也不盡準(zhǔn)確,如微軟Office組件中的Word在對(duì)中文字?jǐn)?shù)統(tǒng)計(jì)時(shí)會(huì)把中文的標(biāo)點(diǎn)符號(hào)也計(jì)算在內(nèi)。
2 基于C語言的字?jǐn)?shù)統(tǒng)計(jì)
本文用C語言來大致描述出如何通過編程來實(shí)現(xiàn)字?jǐn)?shù)統(tǒng)計(jì)功能。均假設(shè)從test.txt文件中得到輸入。所用到的文件指針如下:
FILE *fp;
// 打開文件
if((fp = fopen(\"c:\\\est.txt\", \"r\")) == NULL)
{
printf(\"Can't open file.\");
exit(1);
}
2.1 英文單詞的統(tǒng)計(jì)
對(duì)英文單詞進(jìn)行統(tǒng)計(jì)時(shí),需要考慮它們的ASCII碼即可,主要要分清哪個(gè)字符標(biāo)識(shí)著單詞的開始或結(jié)束,如單詞hello,一旦訪問到字符h就表明進(jìn)入單詞內(nèi)部,直到遇到單詞分隔符如空格、回車等時(shí)認(rèn)為該單詞結(jié)束,將單詞數(shù)加一。簡(jiǎn)要代碼如下:
void countEn(FILE *fp, int *num_e)
{
int word_e = 0; // 英文單詞開始時(shí)設(shè)置 0 標(biāo)記,即在單詞外部
char ch;
while((ch = fgetc(fp)) != EOF)
{
// 判斷是否為字母
if(((ch >= 'a' ch <= 'z') || (ch >= 'A' ch <= 'Z')) word_e == 0)
{
(*num_e)++;
word_e = 1; // 置1表明在單詞內(nèi)部
}
// 如果既不是字母又不是數(shù)字,而且也不小于0的話,即也不是中文字符的話,
// 就視為分隔符
else if((ch > 0 ch < 48) || (ch > 57 ch < 65)
|| (ch > 90 ch < 97) || (ch > 122 ch < 128))
word_e = 0;// 表明在單詞外部
}}
2.2 數(shù)字的統(tǒng)計(jì)
對(duì)數(shù)字進(jìn)行統(tǒng)計(jì)時(shí),也需要考慮它們的ASCII碼,要分清哪個(gè)字符標(biāo)識(shí)著數(shù)字的開始或結(jié)束,如1000,一旦訪問到字符1就表明進(jìn)入數(shù)字內(nèi)部,直到遇到分隔符如空格、回車等時(shí)認(rèn)為該數(shù)字結(jié)束,將數(shù)字?jǐn)?shù)目加一。由于可能存在小數(shù),如10.01,如果遇到“.”,還需要判斷它的下一個(gè)字符是不是為數(shù)字,如果不是則這個(gè)數(shù)字才被認(rèn)為結(jié)束。簡(jiǎn)要代碼如下:
void countDigit(FILE *fp, int *num_d)
{
int word_d = 0;//數(shù)字開始時(shí)設(shè)置 0 標(biāo)記,如1000,即在數(shù)字外部
char ch;
while((ch = fgetc(fp)) != EOF)
{
if((ch >= '0' ch <= '9') word_d == 0)
{
(*num_d)++;
word_d = 1;
}
// 如果既不是字母又不是數(shù)字,而且也不小于0的話,就視為分隔符
else if((ch > 0 ch < 46) || ch == 47 || (ch > 57 ch < 65)
|| (ch > 90 ch < 97) || (ch > 122 ch < 128))
word_d = 0;
}
// 把小數(shù)點(diǎn)看成數(shù)的一部分,如1.55,“.”的ASCII碼值為46
else if(ch == 46 )
{
ch = fgetc(fp);
// 如果“.”之后不再為數(shù)字,則認(rèn)為數(shù)字結(jié)束,將word_d置為0
if(!((ch >= '0' ch <= '9') word_d == 1))
word_d = 0;
}}}
2.3 漢字的統(tǒng)計(jì)
由于漢字由兩個(gè)字節(jié)來描述,其內(nèi)碼范圍為 B0A0~F7A0,而中文標(biāo)點(diǎn)符號(hào)內(nèi)碼的高字節(jié)為A1,所以只要區(qū)分高字節(jié)的不同,就可以區(qū)分開漢字和標(biāo)點(diǎn)了。也就是說,如果一個(gè)字節(jié)大于B0,則意味著有可能是中文漢字,如果下一字節(jié)仍然大于A0,那么這必然是一個(gè)漢字,字?jǐn)?shù)加一,否則不予處理。直到文件讀取結(jié)束。簡(jiǎn)要代碼如下:
void countCN(FILE *fp, int *num_c)
{
char ch;
while((ch = fgetc(fp)) != EOF)
{
// 漢字的內(nèi)碼范圍為 B0A0~F7A0
if(ch < 0)
{
if(((int)ch 0xff) >= 0xB0)
{
ch = fgetc(fp);
if(((int)ch 0xff) >= 0xA0)
(*num_c)++;
}
// 直接讀入漢字的第二個(gè)字節(jié)
else
ch = fgetc(fp);
}}}
3 結(jié)論
對(duì)文檔進(jìn)行字?jǐn)?shù)統(tǒng)計(jì),這在很多場(chǎng)合下均有應(yīng)用,而由于中英文編碼的不同,統(tǒng)計(jì)混合文件中的字?jǐn)?shù)也是比較復(fù)雜的,本文的方法具有較好的健壯性,可以用任何一種編程語言實(shí)現(xiàn)或者移植到其它應(yīng)用程序當(dāng)中。
參考文獻(xiàn):
[1] 吳征.在Delphi中實(shí)現(xiàn)中英文字?jǐn)?shù)統(tǒng)計(jì)[J].電腦迷,2004(3):72.
[2] 于鴻霞.統(tǒng)計(jì)與規(guī)則相結(jié)合的中英文組塊分析[D].哈爾濱:哈爾濱工業(yè)大學(xué),2006.
[3] 李德明.計(jì)算機(jī)漢字內(nèi)碼評(píng)析[J].印刷雜志,1997(5).