久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C標準庫的setlocale()用法筆記

 guitarhua 2012-05-03

C標準庫的setlocale()用法筆記

轉(zhuǎn)自:http:///wp/cc-prog-lang/c-stdlib-setlocale-usage-note/ 

[在此向原文作者說聲謝謝,!若有讀者看到文章轉(zhuǎn)載時請寫該轉(zhuǎn)載地址,不要寫我的BLOG地址,。尊重他人的勞動成果 ^_^ ]

C 和 C++ 的標準庫分別有自己的 locale 操作方法,,C 標準庫的 locale 設(shè)定函數(shù)是 setlocale(),而 C++ 標準庫有 locale 類和流對象的 imbue() 方法,。這篇是我自己的 setlocale() 使用總結(jié),。

Linux的glibc中的setlocale()

具體參考:man 3 setlocale

頭文件與聲明如下:

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

說明

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

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

在Linux下,可以使用 locale -a 命令查看系統(tǒng)中所有已配置的 locale,。用不帶選項的 locale 命令查看當前 Shell 中活動的 locale,。用 locale -m 命令查看locale系統(tǒng)支持的所有可用的字符集編碼。

和locale相關(guān)的包叫做:locales,,locale系統(tǒng)支持的所有可用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 命令,。

當 locale 為 NULL 時,函數(shù)只做取回當前 locale 操作,,通過返回值傳出,,并不改變當前 locale。

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

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

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

Windows的CRT中的setlocale()

具體參考:setlocale - MSDN Run-Time Library Reference

在 Windows CRT 的實現(xiàn)中還有一個使用 wchar_t 作為 locale 名的寬字符版本:_wsetlocale(),。因此,,也有了使用 _TCHAR 宏版本的 setlocale():_tsetlocale()

Windows CRT 實現(xiàn)的 setlocale() 和 glibc 版本的頭文件與聲明相同,,使用方法類似,,如下:

支持的 locale 分類常量:LC_ALL、LC_COLLATE,、LC_CTYPE,、LC_MONETARY、LC_NUMERIC,、LC_TIME,。

請求設(shè)定的 locale 名可以為以下格式(參考MSDN:Language and Country/Region Strings):

  1. lang[_country_region[.code_page]]:雖然形式與 glibc 的相同,當 Windows 的 locale 名并不符合 POSIX 的規(guī)范,,比如采用 GBK 字符集的大陸中文,,POSIX 的名字為:zh_CN.GBK,而在 Windows CRT 中要用:Chinese_People's Republic of China.936,,(-_-^),。

  2. .code_page:可以直接使用代碼頁來設(shè)定 locale,,而且可以使用 .OCP,、.ACP 兩個偽代碼頁,.OCP 表示從系統(tǒng)獲得的當前活動的 OEM 代碼頁,,.ACP 表示從系統(tǒng)獲得的活動 ANSI 代碼頁,。

  3. "":根據(jù) Windows 系統(tǒng)環(huán)境的活動 ANSI 代碼頁來設(shè)定 locale。.OCP,、.ACP,、和環(huán)境代碼頁都受控制面板中“區(qū)域與語言選項”的設(shè)置影響。默認裝完簡體中文版 Windows 后,,活動的 ANSI 代碼頁為:936(即 GBK),,可用 chcp 控制臺程序查看活動代碼頁。

  4. NULL:取回當前 locale,,不改變當前 locale,。

setlocale()的作用和使用例子

當向終端、控制臺輸出 wchar_t 類型的字符時,,需要設(shè)置 setlocale(),,因為通常終端、控制臺環(huán)境自身是不支持 UCS 系列的字符集編碼的,,使用流操作函數(shù)時(如:printf()),,在標準/RT庫實現(xiàn)的內(nèi)部會將 UCS 字符轉(zhuǎn)換成合適的本地 ANSI 編碼字符,轉(zhuǎn)換的依據(jù)就是 setlocale() 設(shè)定的活動 locale,,最后將結(jié)果字符序列傳遞給終端,,對于來自終端的輸入流這個過程剛好相反,。

可以用重定向輸出流到文件的方法驗證上面的機制:無論是 Windows CRT、Linux glibc,、Cygwin glibc,,使用 wprintf() 打印 wchar_t 字符文本時,重定向到文件的內(nèi)容總是 GBK,、UTF-8 等本地 ANSI 編碼,,而不會是 UCS 編碼。

下面是我寫的一個使用 setlocale() 的示例:

01 #ifdef __GNUC__
02   
03 #define CSET_GBK    "GBK"
04 #define CSET_UTF8   "UTF-8"
05   
06 #define LC_NAME_zh_CN   "zh_CN"
07   
08 // ifdef __GNUC__
09 #elif defined(_MSC_VER)
10   
11 #define CSET_GBK    "936"
12 #define CSET_UTF8   "65001"
13   
14 #define LC_NAME_zh_CN   "Chinese_People's Republic of China"
15   
16 // ifdef _MSC_VER
17 #endif
18   
19 #define LC_NAME_zh_CN_GBK       LC_NAME_zh_CN "." CSET_GBK
20 #define LC_NAME_zh_CN_UTF8      LC_NAME_zh_CN "." CSET_UTF8
21 #define LC_NAME_zh_CN_DEFAULT   LC_NAME_zh_CN_GBK
22   
23 void print_current_loc();
24   
25 int main(int argc, char* argv[])
26 {
27     char* locname = NULL;
28     const wchar_t* strzh = L"中文字符串";
29   
30     print_current_loc();
31   
32     // 使用指定的 locale
33     locname = setlocale(LC_ALL, LC_NAME_zh_CN_DEFAULT);
34     if ( NULL == locname )
35     {
36         printf("setlocale() with %s failed.\n", LC_NAME_zh_CN_DEFAULT);
37     }
38     else
39     {
40         printf("setlocale() with %s succeed.\n", LC_NAME_zh_CN_DEFAULT);
41     }
42   
43     print_current_loc();
44   
45     wprintf(L"Zhong text is: %ls\n", strzh);
46   
47     // 使用運行環(huán)境中的 locale 設(shè)置
48     locname = setlocale(LC_ALL, "");
49     if ( NULL == locname )
50     {
51         printf("setlocale() from environment failed.\n");
52     }
53     else
54     {
55         printf("setlocale() from environment succeed.\n");
56     }
57   
58     print_current_loc();
59   
60     wprintf(L"Zhong text is: %ls\n", strzh);
61   
62     puts("End of program.");
63     return 0;
64 }
65   
66 // 打印當前 locale
67 void print_current_loc()
68 {
69     char* locname = setlocale(LC_ALL, NULL);
70     printf("Current locale is: %s\n", locname);
71 }

要使上面程序成功編譯并執(zhí)行,,需要注意一下幾點:

Windows CRT 是不支持 UTF-8 編碼作為 locale 的,,運行時使用 setlocale(LC_ALL, ".65001") 會失敗。

使用 Linux 和 Cygwin 的 glibc 時,,要在終端顯示正確的中文,,需滿足以下條件:

  1. 不要混用 char 和 wchar_t 版本的流操作函數(shù),否則會導致這些函數(shù)運行異常,,我用Cygwin GCC 4測試混用 printf() 和 wprintf() 時,,程序甚至崩掉,所以要將上面程序中 printf() 語句全注釋掉才行,。Window CRT 的實現(xiàn)則沒有這個問題,。

  2. 運行環(huán)境的 locale 設(shè)置要和程序中 setlocale() 設(shè)定的 locale 一致,比如:終端的活動字符集,、環(huán)境變量(一般用 LANG),,要設(shè)置為 *.UTF-8,,才能顯示 setlocale(LC_ALL, "zh_CN.UTF-8") 設(shè)定的 wchar_t 的中文字符,。

  3. 用 GCC 編譯時,要使用 UTF-8 編碼保存源文件,,這是 GCC 在編譯時,,將 wchar_t 文字量(以 L 打頭)正確轉(zhuǎn)換為 UCS 編碼保存在對象文件中的必需條件,用 Native ANSI 編碼(比如:GBK)有 wchar_t 文字量的源文件時,,GCC 會編譯出錯,,Linux 和 Cygwin 的 GCC 都有這個約束。另外在 Linux GCC 使用 UCS-4 編碼保存 wchar_t,,而 Windows 和 Cygwin GCC 使用 UCS-2,。

  4. 用 wprintf() 時,要用 %ls 表示 wchar_t 的字符串,,用 %s 表示 char 的字符串,,具體參考:man 3 wprintf,而 Windows 的實現(xiàn)用 %ls,、%s 都可以正確輸出 wchar_t 字符串,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多