Big-5 Fundamental Functions


typedef short Big5;

首先我們要定義 Big5 的抽象資料結構. 也就是說, 利用 C 的原有資料形態, 定義一個 Big5 的資料形態. 我們需要十六位元, 故最經濟的做法就是用 short 整數形態. 此 Big5 資料形態將與 ASCII 相容. 亦即, 如果 (Big5 c) 代表一個 ASCII 元素, 則 c 的值與 (char c) 相同. 而且 c 可以記錄 EOF 的值.

我們要定義一些標準 Big-5 碼的參數. 這包括: 其首碼範圍, 以及其次碼在低字元的範圍.


#define BL0     64              /* 0x40, low start of Big-5 second byte */
#define BL1     126             /* 0x7E, low end of Big-5 second byte */
#define BH0     161             /* 0xA1, high start of Big-5 second byte */
#define BH1     254             /* 0xFE, high end of Big-5 second byte */

現在, 我們定義幾個基本功能程式的結構和用法. 但是我們不在這裡詳述其程式內容的細節. 如果您想知道, 可以看 C 程式原始碼.


int isfirst(int)
int issecond(int)

如果 c 屬於 Big-5 首碼範圍, isfirst(c) 傳回 1 (TRUE), 否則傳回 0 (FALSE). 如果 c 屬於 Big-5 次碼範圍, issecond(c) 傳回 1 (TRUE), 否則傳回 0 (FALSE).


Big5 fgetc5(FILE*)
Big5 getchar5()
Big5 fgetbig5(FILE*)

fgetc5(fp) 從檔案 fp 中讀入一個字元. 它可能是個 ASCII 字, 可能是個 Big-5 字, 也可能是 EOF. fgetc5(fp) 假設 fp 中的文字是安全的. 意思是說, fp 中的文字, 若非 ASCII 就是 Big-5, 沒有例外. getchar5() 就是 fgetct(stdin). fgetbig5(fp) 的功能與 fgetc5(fp) 相同, 但是比較小心一點. 它會注意是否有 extended ASCII 的碼存在. 但是若連續兩個 extended ASCII 碼 恰好落在 Big-5 碼的範圍之內, 那就當然會被解釋成 Big-5 碼.

如果 fp 檔案內並沒有發生不在 Big-5 範圍內的 extended ASCII 碼. 簡單地說, 並沒有例外情形發生, 那麼 fgetbig5() 並不會比 fgetc5() 花費時間. 我有一個簡單的測驗程式 test_get.c (test_get.c), 並附有在一台 DEC 3400 上的測驗結果.

但是, 若真的要快速讀入檔案, 必須呼叫 read() 系統程式. 問題是, 用 read() 讀進來的東西是固定長度的, 比如說 8192 個 char. 我們要把這 8192 個 char 轉換成 Big5, 但 Big5 用掉兩個 char. 所以, 轉換之後, 可能剩下一個 char 必須等待下一次的 read() 的第一個 char. 而且, 使用 read() 之後, 字元都在記憶體內, 所以不能使用 fgetc5() 之類的程式. 您必須自己寫個類似 fgetc5() 的程式片段. 我可以給您一個範例程式 test_read.c, 並附有在一台 DEC 3400 上的測驗結果. 和前面的 test_get.c 比起來, 真的快了很多. 但是程式就比較難寫. 注意, 您不該一口氣將 read() 讀進來的 char 全部轉成了 Big5 字串之後, 才處理其資料. 因為這樣就相當於您將每個字元多讀了一次. 確實該怎麼做, 應該是由您的問題決定的. 例如, 在我的範例程式中的 do_something() 子程式中, 只是把讀入的字寫出去.


int fputc5(Big5, FILE*)
int putchar5(Big5)

fputc5(c, fp) 就是把 (Big5 c) 寫到 fp 檔案內. 而 putchar5(c) 就是 fputc5(c, stdout).


int getfirst(Big5)
int getsecond(Big5)

getfirst(c) 就是取出 (Big5 c) 的首碼, 應在 161 到 254 之間. getsecond(c) 就是取出 (Big5 c) 的次碼, 應在 161 到 254 之間或是 64 到 126 之間.


int linear(Big5)
Big5 b5(int)

如果 (Big5 c) 是個字, 則 linear(c) 回應其在 Big-5 碼內的順序編號. 為了配合 array 編號的方便, 從 0 開始編號. 所以一的字號是 0, 龘的字號是 13052. 外加七個倚天字, 編在最後: 13053--13059. 如果 (Big5 c) 不是個標準 Big-5 字集中定義的字, (這包括全形符號, 首碼不在 164--198, 201--249 之間者), 則一律回應 -1. 其實 linear() 還有個小麻煩, 我目前不想去理它. 那就是, 當首碼是 198 或 249 的時候, 次碼並沒有擺滿. 但是, 此程式沒去檢查這件事.

如果 (int n) 是個介於 0 和 13059 的整數, b5(n) 回應其對應的 ET/Big-5 字碼. 否則, 回應□ (0xA1, 0xBC).

注意, Big-5 的順序編號並不是中國字的順序編號. 除了它的編碼系統內部的錯誤之外, 次常用字與常用字的分隔, 也使得排序出現問題. 比如說, 次常用字的万, 其 Big-5 字號必定比常用字的龍還大. 但是照一般對中國字排序的認識, 筆劃少且部首序比較小的万, 總該排在龍的前面.


int isphon(Big5)
Big5 phon(int)

inphon(c) 檢查 (Big5 c) 是否為一個注音符號或聲調符號, 如果不是, 回應 0; 如果是, 回應正整數, 即這些符號的正確順序. 我們排的順序是, 輕聲 1, 四個聲調 2--5, 三十七個注音符號 6--42. 如果 (int n) 是介於 1 和 42 之間的整數, 則 phon(n) 回應一個 Big-5 碼, 對應其注音符號或聲調符號字碼. 否則, 回應□ (0xA1, 0xBC).

最後, 我建議您選擇閱讀以下幾種相關文件:


Created: Nov 26, 1996
Last Revised: Feb 18, 1997
© Copyright 1996 Wei-Chang Shann

shann@math.ncu.edu.tw