日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux c编译 utf-8,在Linux C编程中使用Unicode和UTF-8

發(fā)布時(shí)間:2023/12/31 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux c编译 utf-8,在Linux C编程中使用Unicode和UTF-8 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在Linux C編程中使用Unicode和UTF-8

目前各種Linux發(fā)行版都支持UTF-8編碼,當(dāng)前系統(tǒng)的語(yǔ)言和字符編碼設(shè)置保存在一些環(huán)境變量中,可以通過(guò)locale命令查看:$ locale

LANG=en_US.UTF-8

LC_CTYPE="en_US.UTF-8"

LC_NUMERIC="en_US.UTF-8"

LC_TIME="en_US.UTF-8"

LC_COLLATE="en_US.UTF-8"

LC_MONETARY="en_US.UTF-8"

LC_MESSAGES="en_US.UTF-8"

LC_PAPER="en_US.UTF-8"

LC_NAME="en_US.UTF-8"

LC_ADDRESS="en_US.UTF-8"

LC_TELEPHONE="en_US.UTF-8"

LC_MEASUREMENT="en_US.UTF-8"

LC_IDENTIFICATION="en_US.UTF-8"

LC_ALL=

常用漢字也都位于BMP中,所以一個(gè)漢字的存儲(chǔ)通常占3個(gè)字節(jié)。例如編輯一個(gè)C程序:#include int main(void)

{

printf("你好\n");

return 0;

}

源文件是以UTF-8編碼存儲(chǔ)的:$ od -tc nihao.c

0000000 # i n c l u d e < s t d i o .

0000020 h > \n \n i n t m a i n ( v o i

0000040 d ) \n { \n \t p r i n t f ( " 344 275

0000060 240 345 245 275 \ n " ) ; \n \t r e t u r

0000100 n 0 ; \n } \n

0000107

其中八進(jìn)制的344 375 240(十六進(jìn)制e4 bd a0)就是“你”的UTF-8編碼,八進(jìn)制的345 245 275(十六進(jìn)制e5 a5 bd)就是“好”。把它編譯成目標(biāo)文件,"你好\n"這個(gè)字符串就成了這樣一串字節(jié):e4 bd a0 e5 a5 bd 0a 00,漢字在其中仍然是UTF-8編碼的,一個(gè)漢字占3個(gè)字節(jié),這種字符在C語(yǔ)言中稱為多字節(jié)字符(Multibyte Character)。運(yùn)行這個(gè)程序相當(dāng)于把這一串字節(jié)write到當(dāng)前終端的設(shè)備文件。如果當(dāng)前終端的驅(qū)動(dòng)程序能夠識(shí)別UTF-8編碼就能打印出漢字,如果當(dāng)前終端的驅(qū)動(dòng)程序不能識(shí)別UTF-8編碼(比如一般的字符終端)就打印不出漢字。也就是說(shuō),像這種程序,識(shí)別漢字的工作既不是由C編譯器做的也不是由libc做的,C編譯器原封不動(dòng)地把源文件中的UTF-8編碼復(fù)制到目標(biāo)文件中,libc只是當(dāng)作以0結(jié)尾的字符串原封不動(dòng)地write給內(nèi)核,識(shí)別漢字的工作是由終端的驅(qū)動(dòng)程序做的。

但是僅有這種程度的漢字支持是不夠的,有時(shí)候我們需要在C程序中操作字符串里的字符,比如求字符串"你好\n"中有幾個(gè)漢字或字符,用strlen就不靈了,因?yàn)閟trlen只看結(jié)尾的0字節(jié)而不管字符串里存的是什么,求出來(lái)的是字節(jié)數(shù)7。為了在程序中操作Unicode字符,C語(yǔ)言定義了寬字符(Wide Character)類型wchar_t和一些庫(kù)函數(shù)。在字符常量或字符串字面值前面加一個(gè)L就表示寬字符常量或?qū)捵址?#xff0c;例如定義wchar_t c = L'你';,變量c的值就是漢字“你”的31位UCS編碼,而L"你好\n"就相當(dāng)于{L'你', L'好', L'\n', 0},wcslen函數(shù)就可以取寬字符串中的字符個(gè)數(shù)。看下面的程序:#include #include int main(void)

{

if (!setlocale(LC_CTYPE, "")) {

fprintf(stderr, "Can't set the specified locale! "

"Check LANG, LC_CTYPE, LC_ALL.\n");

return 1;

}

printf("%ls", L"你好\n");

return 0;

}

寬字符串L"你好\n"在源代碼中當(dāng)然還是存成UTF-8編碼的,但編譯器會(huì)把它變成4個(gè)UCS編碼0x00004f60 0x0000597d 0x0000000a 0x00000000保存在目標(biāo)文件中,按小端存儲(chǔ)就是60 4f 00 00 7d 59 00 00 0a 00 00 00 00 00 00 00,用od命令查看目標(biāo)文件應(yīng)該能找到這些字節(jié)。$ gcc hihao.c

$ od -tx1 a.out

printf的%ls轉(zhuǎn)換說(shuō)明表示把后面的參數(shù)按寬字符串解釋,不是見(jiàn)到0字節(jié)就結(jié)束,而是見(jiàn)到UCS編碼為0的字符才結(jié)束,但是要write到終端仍然需要以多字節(jié)編碼輸出,這樣終端驅(qū)動(dòng)程序才能識(shí)別,所以printf在內(nèi)部把寬字符串轉(zhuǎn)換成多字節(jié)字符串再write出去。事實(shí)上,C標(biāo)準(zhǔn)并沒(méi)有規(guī)定多字節(jié)字符必須以UTF-8編碼,也可以使用其它的多字節(jié)編碼,在運(yùn)行時(shí)根據(jù)環(huán)境變量確定當(dāng)前系統(tǒng)的編碼,所以在程序開(kāi)頭需要調(diào)用setlocale獲取當(dāng)前系統(tǒng)的編碼設(shè)置,如果當(dāng)前系統(tǒng)是UTF-8的,printf就把UCS編碼轉(zhuǎn)換成UTF-8編碼的多字節(jié)字符串再write出去。一般來(lái)說(shuō),程序在做內(nèi)部計(jì)算時(shí)通常以寬字符編碼,如果要存盤或者輸出給別的程序,或者通過(guò)網(wǎng)絡(luò)發(fā)給別的程序,則采用多字節(jié)編碼。

關(guān)于Unicode和UTF-8本節(jié)只介紹了最基本的概念,部分內(nèi)容出自,讀者可進(jìn)一步參考這篇文章。

總結(jié)

以上是生活随笔為你收集整理的linux c编译 utf-8,在Linux C编程中使用Unicode和UTF-8的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。