1. 程式人生 > >修改 /var/lib/locales/supported.d/local 檔案(使用 locale -a 命令檢視系統中所有已配置的 locale)

修改 /var/lib/locales/supported.d/local 檔案(使用 locale -a 命令檢視系統中所有已配置的 locale)

轉自:http://zyxhome.org/wp/cc-prog-lang/c-stdlib-setlocale-usage-note/ 

      http://www.west263.com/info/html/caozuoxitong/FreeBSD/20090513/126191.html

C 和 C++ 的標準庫分別有自己的 locale 操作方法,C 標準庫的 locale 設定函式是 setlocale(),而 C++ 標準庫有 locale 類和流物件的 imbue() 方法。這篇是我自己的 setlocale() 使用總結。

Linux的glibc中的setlocale()

具體參考:man 3 setlocale

標頭檔案與宣告如下:

1 #include <locale.h>
2 charsetlocale(int category, const char* locale);

說明

category:為locale分類,表達一種locale的領域方面,通常有下面這些預定義常量:LC_ALL、LC_COLLATE、LC_CTYPE、LC_MESSAGES、LC_MONETARY、LC_NUMERIC、LC_TIME,其中 LC_ALL 表示所有其它locale分類的並集。

locale:為期望設定的locale名稱字串,在Linux/Unix環境下,通常以下面格式表示locale名稱:language[_territory][.codeset][@modifier],language 為 ISO 639 中規定的語言程式碼,territory 為 ISO 3166 中規定的國家/地區程式碼,codeset 為字符集名稱。

在Linux下,可以使用 locale -a 命令檢視系統中所有已配置的 locale。用不帶選項的 locale 命令檢視當前 Shell 中活動的 locale。用 locale -m

 命令檢視locale系統支援的所有可用的字符集編碼。

和locale相關的包叫做:locales,locale系統支援的所有可用locale在檔案:/usr/share/i18n/SUPPORTED 中列出。

在Debian下,可用 dpkg-reconfigure locales 命令重新配置 locale,也可以手工修改 /etc/locale.gen 檔案,然後執行 locale-gen 命令。

在Ubuntu下,修改 /var/lib/locales/supported.d/local 檔案,配置新的 locale,然後執行 locale-gen 命令。

 

我在我用的fedora14的linux虛擬機器中執行locale 返回如下:

[[email protected] ~]$ locale
LANG=zh_CN.utf8
LC_CTYPE="zh_CN.utf8"
LC_NUMERIC="zh_CN.utf8"
LC_TIME="zh_CN.utf8"
LC_COLLATE="zh_CN.utf8"
LC_MONETARY="zh_CN.utf8"
LC_MESSAGES="zh_CN.utf8"
LC_PAPER="zh_CN.utf8"
LC_NAME="zh_CN.utf8"
LC_ADDRESS="zh_CN.utf8"
LC_TELEPHONE="zh_CN.utf8"
LC_MEASUREMENT="zh_CN.utf8"
LC_IDENTIFICATION="zh_CN.utf8"
LC_ALL=

當 locale 為 NULL 時,函式只做取回當前 locale 操作,通過返回值傳出,並不改變當前 locale。

當 locale 為 "" 時,根據環境的設定來設定 locale,檢測順序是:環境變數 LC_ALL,每個單獨的locale分類LC_*,最後是 LANG 變數。為了使程式可以根據環境來改變活動 locale,一般都在程式的初始化階段加入下面程式碼:setlocale(LC_ALL, "")。

當C語言程式初始化時(剛進入到 main() 時),locale 被初始化為預設的 C locale,其採用的字元編碼是所有本地 ANSI 字符集編碼的公共部分,是用來書寫C語言源程式的最小字符集(所以才起locale名叫:C)。

當用 setlocale() 設定活動 locale 時,如果成功,會返回當前活動 locale 的全名稱;如果失敗,會返回 NULL。

 

locale 是一組 C 程式語言處理自然語言(文字)的程式介面, 也可以簡單的說,locale 就是一組地區性語言的資訊。由國家語言和各地習俗影響所決定的慣例,或代表一個地理區域的定義所組成,這些慣例包含文字、日期、數字、貨幣格式和排序等等。這代表著 locale 可讓程式的輸出可以直接反應地方區域性的文化。

C 語言的 locale 定義,分為下列各大類:
LC_ALL 指定所有的 Locale
LC_CTYPE 字元定義 (包含字元分類與轉換規則)
LANG 語言顯示
LC_MESSAGES 訊息顯示
LC_TIME 時間格式
LC_NUMERIC 數字格式
LC_MONETARY 貨幣格式
LC_COLLATE 字母順序與特殊字元比較

其中與一般使用者息息相關的,是字元定義 (LC_CTYPE) 與語言顯示 (LANG)。LC_CTYPE 直接關係到某些字元或內碼在目前的 locale 下是否可列印?要如何轉換字碼?對應到哪一個字?.... 等等。LANG 則關係到軟體的訊息輸出是不是符合地域性,例如 :我們需要的是中文。而一個真正完整支援 locale 系統, 是當使用者在 shell prompt 下,直接設好環境變數後,則馬上就能切換到那個語言了。當 LC_MESSAGES、LC_TIME、LC_NUMERIC、 LC_MONETARY 等沒有設定的時候,會直接取用 LANG 的環境設定值。
設定 Locale 的字元定義為臺灣地區的 utf-8 繁體中文碼定義, 有了正確的 locale 的定義後,使得任何地區的語文,只要在加入適當的 locale data 之後,C Library 就能正確地處理軟體顯示訊息, 而我們使用的中文當然也不例外,而目前常用的中文 locale data 就是 zh_TW.utf-8,代表的就是中文語系(zh)臺灣地區(TW) 使用utf-8編碼系統(utf-8)。

其中與一般使用者息息相關的,是字元定義 (LC_CTYPE) 與語言顯示 (LANG)。LC_CTYPE 直接關係到某些字元或內碼在目前的 locale 下是否可列印?要如何轉換字碼?對應到哪一個字?.... 等等。LANG 則關係到軟體的訊息輸出是不是符合地域性,例如 :我們需要的是中文。而一個真正完整支援 locale 系統, 是當使用者在 shell prompt 下,直接設好環境變數後,則馬上就能切換到那個語言了。當 LC_MESSAGES、LC_TIME、LC_NUMERIC、 LC_MONETARY 等沒有設定的時候,會直接取用 LANG 的環境設定值。
設定 Locale 的字元定義為臺灣地區的 utf-8 繁體中文碼定義, 有了正確的 locale 的定義後,使得任何地區的語文,只要在加入適當的 locale data 之後,C Library 就能正確地處理軟體顯示訊息, 而我們使用的中文當然也不例外,而目前常用的中文 locale data 就是 zh_TW.utf-8,代表的就是中文語系(zh)臺灣地區(TW) 使用utf-8編碼系統(utf-8)。
 locale 命名規則:語言_地區名.字元編碼名稱
當一個程式啟動時,系統會預設給它一個初始 locale,稱為 POSIX 或 C locale。在此 locale 下,程式的表現會與傳統的 C 語言中一樣, 使用英文做訊息輸出,只能處理英文等 ASCII 碼等等。如果該程式有支援 I18N,也就是說它有按照 I18N 的標準來寫,則它在啟動後就會馬上呼叫系統函式來改變它的 locale, 如此它就搖身一變,變成可以處理該 locale 所代表的地區語文了。
zh_TW.utf-8 是目前臺灣內廣泛使用的 locale, zh 是華語(Chinese),1998 年 ISO639 裡面以兩個英文字母來代表語言編碼, 這個縮寫據筆者所知沒有任何含義,而 TW 代表的就是臺灣(Taiwan) 地區的縮寫,最後的 utf-8 則是編碼方式。
locale 設定檔在編譯後, 則是儲存在 /usr/share/locale/ 目錄下, 以 zh_TW.utf-8 locale 為例,該目錄中就包含了 LC_COLLATE、LC_CTYPE、 LC_TIME。
而 LC_MESSAGES 則是儲存在 /usr/local/share/locale/zh_TW/LC_MESSAGES/ 或是/usr/X11R6/share/locale/zh_TW.utf-8/ 底下。由於 LC_MESSAGES 類別掌管的是程式訊息輸出所用的語言,而且不同程式間的訊息都不會一樣,因此它不能像其他類別一樣,只提供單一一個資料檔即可。相反的,在這裡所採取的方式是由各應用程式自行提供它們的訊息資料檔, 並統一放在各 locale 的 LC_MESSAGES 的目錄下。例如 mutt 程式,其訊息的部分除了英文以外,可能還同時提供了繁體中文、簡體中文、 日文、法文等翻譯,因此,在以上這些語文所代表的 locale 中, 其底下的 LC_MESSAGES 目錄中都會有一份屬於 mutt 程式的訊息資料檔。 換句話說,在 I18N 架構下,程式訊息部分是與程式分離的, 如此才能分別對各 locale 做 ``區域化'' (即翻譯成各地區的語言)。 如此,當 mutt 在執行時,系統會根據目前它的 LC_MESSAGES locale 設定去找找看有沒有它的訊息資料檔存在,有的話就以該語言做訊息輸出, 否則的話則以 C locale 的方式 (即英文) 來輸出訊息。

zh_CN.GB2312到底是在說什麼?
Locale 是軟體在執行時的語言環境, 它包括語言(Language), 地域 (Territory) 和字符集(Codeset)。一個locale的書寫格式為: 語言[_地域[.字符集]]. 所以說呢,locale總是和一定的字符集相聯絡的。下面舉幾個例子:
1、我說中文,身處中華人民共和國,使用國標2312字符集來表達字元。
zh_CN.GB2312=中文_中華人民共和國+國標2312字符集。
2、我說中文,身處中華人民共和國,使用國標18030字符集來表達字元。
zh_CN.GB18030=中文_中華人民共和國+國標18030字符集。
3、我說中文,身處中華人民共和國臺灣省,使用國標Big5字符集來表達字元。
zh_TW.BIG5=中文_臺灣.大五碼字符集
4、我說英文,身處大不列顛,使用ISO-8859-1字符集來表達字元。
en_GB.ISO-8859-1=英文_大不列顛.ISO-8859-1字符集
5、我說德語,身處德國,使用UTF-8字符集,習慣了歐洲風格。
[email protected]=德語_德國.UTF-8字符集@按照歐洲習慣加以修正
注意不是[email protected],所以完全的locale表達方式是
[語言[_地域][.字符集] [@修正值]
生成的locale放在/usr/lib/locale/目錄中,並且每個locale都對應一個資料夾,也就是說建立了[email protected] locale之後,就生成/usr/lib/locale/[email protected]/目錄,裡面是具體的每個locale的內容。
什麼是字符集?
字符集就是字元,尤其是非英語字元在系統內的編碼方式,也就是通常所說的內碼,所有的字符集都放在 /usr/share/i18n/charmaps,所有的字符集也都是用Unicode編號索引的。Unicode用統一的編號來索引目前已知的全部的符號而字符集則是這些符號的編碼方式,或者說是在網路傳輸,計算機內部通訊的時候,對於不同字元的表達方式,Unicode是一個靜態的概念,字符集是一個動態的概念,是每一個字元傳遞或傳輸的具體形式。就像Unicode編號U59D0是代表姐姐的“姐”字,但是具體的這個字是用兩個位元組表示,三個位元組,還是四個位元組表示,是字符集的問題。例如:UTF-8字符集就是目前流行的對字元的編碼方式,UTF-8用一個位元組表示常用的拉丁字母,用兩個位元組表示常用的符號,包括常用的中文字元,用三個表示不常用的字元,用四個位元組表示其他的古靈精怪的字元。而GB2312字符集就是用兩個位元組表示所有的字元。需要提到一點的是Unicode除了用編號索引全部字元以外,本身是用四個位元組儲存全部字元,這一點在談到掛載windows分割槽的時候是非常重要的一個概念。所以說你也可以把Unicode看作是一種字符集(我不知道它和UTF-32的關係,反正UTF-32就是用四個位元組表示所有的字元的),但是這樣表述符號是非常浪費資源的,因為在計算機世界絕大部分時候用到的是一個位元組就可以搞定的26個字母而已。所以才會有UTF-8,UTF-16等等,要不然大同世界多好,省了這許多麻煩.

 

通常這幾個函式一起用,用於編寫本地化程式。
setlocale
bindtextdomain
textdomain
gettext

 

http://blog.sina.com.cn/s/blog_70f157930101jlz2.html