國際化程序實現步驟:
國際化(Internationalization,簡寫為I18N)是指軟件在設計結構和機制上支持多語言的擴展特性,其功能和代碼設計不針對某一特定語言和地域。
一:基本實現步驟
1 編輯源程序
用 vim編輯器編輯源程序。注意:要順利實現程序國際化,源程序應當包含相應的標準頭文件,主函數中要調用相關的函數,如庫libintl,函數setlocale(),bindtextdomain(),textdomain()等。
如下程序為簡單的示例:
#include<stdio.h>
>#include<locale.h>
>#include<libintl.h>
>#include<stdlib.h>
#define _(String) gettext (String)
int main(int argc,char**argv)
{
setlocale(LC_ALL,"");
bindtextdomain("gettext",".");
textdomain("gettext");
printf("%s\n",_("one world,one dream!"));
return 0;
}
2 編譯源程序
用gcc命令對源程序進行編譯,生成可執行文件。執行后,可以顯示源程序中的輸入函數的字符。命令示例:
gcc -o gettext gettext.c
3 創建翻譯文件模板pot
用xggetxt命令提取源程序中的翻譯信息,創建翻譯文件模板pot(Portable Object Template可移植的對象模板)文件。命令示例:
xgettext –keyword=_ gettext.c -o gettext.pot
4 由pot生成可移植對象po文件
每一種語言都有其可移植的對象文件,即po(Portable Object )文件。該文件是由一對對的msgid和msgstr組成的,其中,msgid表示從程序中提取的信息,msgstr表示譯文。命令示例:
cp gettext.pot gettext.po
5 編輯po文件中的翻譯字符,修改字符的編碼
用gedit或vim編輯器編輯po文件,翻譯相關信息,并將charset改為UTF-8,否則不可編碼。完成后,保存文件。注意:如果要實現多種語言,此時應復制多分po文件,并分別進行翻譯。命令示例:
gedit gettext.po或vim gettext.po
6 由po文件生成二進制mo文件
用msgfmt命令將po文件轉為二進制mo(MachineObject)文件,供計算機讀取執行。命令示例:
msgfmt gettext.po -o gettext.mo
7 將mo文件放在正確的目錄結構下
mo文件存放位置是否正確是能否實現程序國際化的關鍵。一般情形下,應將其放在相應地區的locale下相應的子目錄中。通常默認目錄結構為/usr/locale/share/local,因此本例中生成的mo應放在該目錄下相應的子目錄中。但是,由于程序中setlocale()函數設定在當前目錄結構下查找翻譯信息,因此只需在當前目錄(即源程序所在目錄)下新建相應的地區目錄即可。如本例中,可以創建如下目錄結構:
zh_CN/LC_MESSAGES/和en_US/LC_MESSAGES/
建好目錄后,分別將兩個不同的mo文件放在這兩目錄下
8 設置環境變量
本示例程序會從當前的環境設定LANG來讀取地區信息,因此需要設置LANG,如下。注意:每次只能設置一個地區。
LANG=zh_CN.UTF-8
LANG=en_US.UTF-8
9 執行程序,得到結果
在終端界面運行 ./gettext 即可得到所要顯示的結果。
二:國際化程序的升級
調試程序的過程中,對源程序進行相應的修改是不可避免的。如何在源程序修改之后,仍能正確的顯示當前新修改的翻譯,同時又有效利用原來的翻譯信息以提高效率,即如何對國際化程序進行“升級”呢?
采用如下步驟可以解決此問題。
1 修改(增、刪)源程序
2 運行xgettext生成新的pot文件
命令示例:
xgettext –keyword=_ gettext.c -o gettext.pot
3 將原程序的po文件更名,以區分新pot文件將生成的po文件
命令示例:
mv gettext.po old_gettext.po
4 運行msgmerge將新、舊pot文件進行比較、合并,生成升級版本的po文件
命令示例:
msgmerge old_gettext.po gettext.pot –output-file gettext.po
或者可以使用poedit的POT導入功能
5 為了記錄新舊pot的區別,可以用diff命令記錄下,兩次pot文件中的異同。
命令示例:
diff -u old_gettext.po gettext.po old_gettext.diff
6 在第4步生成新的po文件生成后,可以刪除原來的po文件,以免干擾。
命令示例:
rm -f old_gettext.po
7 將新生成的po文件生成mo文件
命令示例:
msgfmt gettext.po -o gettext.mo
8 將新生成的mo文件放在正確的目錄結構下
9 設置環境變量
10 執行程序,得到新的結果
三:注意的一些問題
1 源程序中的setlocale()函數與mo文件的目錄結構應相一致,否則不能得到正確的結果。
2 編輯po文件時,注意要將字符調整為可移植的編碼UTF-8,才可以得到正確結果。否則會有如下警告:
(gettext.po:警告:字符集“CHARSET”不是可移植的編碼名稱。將消息轉換為用戶字符集可能不工作。)
3 設置多個環境變量(地區)時,要拷貝多份po并分別進行編輯,并將各自生成的mo文件放在正確的目錄下。
4 修改源程序對其進行國際化升級后,應刪除原程序(修改前)的可執行文件,否則不能得到修改后的程序的運行結果
四:對源程序的一些解釋
#include<stdio.h>
#include<locale.h> //定義本地化函數。
#include<libintl.h>//包含gettext庫,gettext是GUN為解決程序國際化問題專門建立的一套工具和庫。
#include<stdlib.h>
#define _(String) gettext (String)
int main(int argc,char**argv)
{
setlocale(LC_ALL,"");//設置本程序的環境變量(即指特定地區locale),第一參數是命令的作用域,可以指日期、貨幣、數字、文本的顯示樣式;第二參數是一個文本字符串,標志你希望使用哪個地區。若設置成一個空的字符串,則程序會從LANG環境變量獲取地區信息。
bindtextdomain("gettext",".");//告訴gettext最終的生成的翻譯文件mo的位置,“.”表示在當前目錄下尋找mo文件。
textdomain("gettext");//設定翻譯環境,即指定使用gettext的翻譯。
printf("%s\n",_("one world,one dream!"));
return 0;
}