Locale: 字符集(character set).

char ios

可被應用於全部8bit以及8bit如下的字符集,例如: US-ASCII,ISO-Latin-1和ISO-Latin-9以及UTF-8.程序員

 

char16_tweb

可被用於UCS-2,也可被用於UTF-16的code unit(代碼單元).算法

 

char32_t編程

可被用於UCS-4/UTF-32.網絡

 

wchar_tide

它一般等價於char16_t或者char32_t.函數

 

US-ASCII編碼

7-bit字符集,於1963年完成標準化,用於電傳打字機和其餘設備,最開始的16個字符是不可打印的。spa

 

ISO-Latin-1或ISO-8859-1

這是一個8bit的字符集,於1987年完成標準提供西歐語言的全部字符,這個字符集也是下面全部字符集的基礎.

 

UCS-2

這是一個16bit的定長字符集(2byte),提供Universal Character Set(全球字符集)和Unicode(統一碼)中最重要的65536個字符.

 

UTF-8

這是個multi-byte字符集,使用1-4個8bit值,用來表現Universal Character Set(全球字符集)和Unicode(統一碼)的全部字符.主要被普遍的應用於萬維網(world wide web).

 

UTF-16

這也是一個multi-byte字符集,使用1-2 code unit(每一個16bit),用來表現Universal Character Set(全球字符集)和Unicode(贊成碼)之全部標準化字符.

 

UCS-4或UTF-32

這個32bit的定長字符集(4byte),提供Unversal Character Set(全球字符集)和Unicode(統一碼)之全部標準化字符.

 

多字節和寬字符文本:

1,在多字節(Multibyte)表示法中,字符所用的byte是變更的。一個1-byte字符(例如 ISO-Latin-1字符)後面再跟1個,2個或者3個byte,例如中文或者日文。

2,寬字符(wide-character)表示法,字符所用的byte數目固定,與其所表示的字符無關,典型的byte個數是2個或者4個.

 

在咱們瞭解Unicode以前首先了解一下GB,GBK等待國產字符集.

做者:Tuxify
連接:https://www.zhihu.com/question/19677619/answer/12616362
1, GB2312-80
GB 2312 或 GB 2312-80 是中國國家標準簡體中文字符集,全稱《信息交換用漢字編碼字符集·基本集》,又稱GB0,由中國國家標準總局發佈,1981年5月1日實施。GB2312編碼通行於中國大陸;新加坡等地也採用此編碼。中國大陸幾乎全部的中文系統和國際化的軟件都支持GB 2312。

GB 2312標準共收錄6763個漢字,其中一級漢字3755個,二級漢字3008個;同時收錄了包括拉丁字母、希臘字母、日文平假名及片假名字母、俄語西裏爾字母在內的682個字符。

  • GB 2312的出現,基本知足了漢字的計算機處理須要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。
  • 對於人名、古漢語等方面出現的罕用字,GB 2312不能處理,這致使了後來GBK及GB 18030漢字字符集的出現。


GB2312對任意一個圖形字符都採用兩個字節表示,並對所收漢字進行了「分區」處理,每區含有94個漢字/符號,分別對應第一字節和第二字節。這種表示方式也稱爲區位碼。

  • 01-09區爲特殊符號。
  • 16-55區爲一級漢字,按拼音排序。
  • 56-87區爲二級漢字,按部首/筆畫排序。

10-15區及88-94區則未有編碼。
GB2312的編碼範圍爲2121H-777EH,與ASCII有重疊,通行方法是將GB碼兩個字節的最高位置1以示區別。

2 ,GBK
GBK漢字內碼擴展規範K爲漢語拼音 Kuo Zhan(擴展)中「擴」字的聲母。英文全稱Chinese Internal Code Specification。

GBK共收入21886個漢字和圖形符號,包括:

  • GB2312中的所有漢字、非漢字符號。
  • BIG5中的所有漢字。
  • 與ISO 10646相應的國家標準GB13000中的其它CJK漢字,以上合計20902個漢字。
  • 其它漢字、部首、符號,共計984個。

GBK向下與GB2312 徹底兼容,向上支持ISO 10646國際標準,在前者向後者過渡過程當中起到的承上啓下的做用。

GBK 採用雙字節表示,整體編碼範圍爲8140-FEFE之間,首字節在81-FE之間,尾字節在40-FE之間,剔除XX7F一條線。GBK編碼區分三部分:

  • 漢字區 包括

GBK/2:0xB0A1-F7FE, 收錄GB2312漢字6763個,按原序排列;
GBK/3:0x8140-A0FE,收錄CJK漢字6080個;
GBK/4:0xAA40-FEA0,收錄CJK漢字和增補的漢字8160個。

  • 圖形符號區 包括

GBK/1:0xA1A1-A9FE,除GB2312的符號外,還增補了其它符號
GBK/5:0xA840-A9AO,擴除非漢字區。

  • 用戶自定義區

GBK區域中的空白區,用戶能夠本身定義字符。

3 ,GB18030
GB 18030,全稱:國家標準GB 18030-2005《信息技術中文編碼字符集》,是中華人民共和國現時最新的內碼字集,是GB 18030-2000《信息技術信息交換用漢字編碼字符集基本集的擴充》的修訂版。
GB 18030與GB 2312-1980徹底兼容,與GBK基本兼容,支持GB 13000及Unicode的所有統一漢字,共收錄漢字70244個。

  • 與 UTF-8 相同,採用多字節編碼,每一個字能夠由1個、2個或4個字節組成。
  • 編碼空間龐大,最多可定義161萬個字符。
  • 支持中國國內少數民族的文字,不須要動用造字區。
  • 漢字收錄範圍包含繁體漢字以及日韓漢字

GB18030 編碼是一二四字節變長編碼。

  • 單字節,其值從0到0x7F,與 ASCII 編碼兼容。
  • 雙字節,第一個字節的值從0x81到0xFE,第二個字節的值從0x40到0xFE(不包括0x7F),與 GBK標準基本兼容。
  • 四字節,第一個字節的值從0x81到0xFE,第二個字節的值從0x30到0x39,第三個字節從0x81到0xFE,第四個字節從0x30到0x39。

 

ASCII,GB(K),Unicode的區別與聯繫:
連接:https://www.zhihu.com/question/19677619/answer/27516663

好久好久之前,有一羣人,他們決定用8個能夠開合的晶體管來組合成不一樣的狀態,以表示世界上的萬物。他們看到8個開關狀態是好的,因而他們把這稱爲」字節「。再後來,他們又作了一些能夠處理這些字節的機器,機器開動了,能夠用字節來組合出不少狀態,狀態開始變來變去。他們看到這樣是好的,因而它們就這機器稱爲」計算機「。

開始計算機只在美國用。八位的字節一共能夠組合出256(2的8次方)種不一樣的狀態。 他們把其中的編號從0開始的32種狀態分別規定了特殊的用途,一但終端、打印機趕上約定好的這些字節被傳過來時,就要作一些約定的動做。趕上0×10, 終端就換行,趕上0×07, 終端就向人們嘟嘟叫,例好趕上0x1b, 打印機就打印反白的字,或者終端就用彩色顯示字母。他們看到這樣很好,因而就把這些0×20如下的字節狀態稱爲」控制碼」。他們又把全部的空 格、標點符號、數字、大小寫字母分別用連續的字節狀態表示,一直編到了第127號,這樣計算機就能夠用不一樣字節來存儲英語的文字了。你們看到這樣,都感受 很好,因而你們都把這個方案叫作ANSI 的」Ascii」編碼(American Standard Code for Information Interchange,美國信息互換標準代碼)。當時世界上全部的計算機都用一樣的ASCII方案來保存英文文字。

後來,就像建造巴比倫塔同樣,世界各地的都開始使用計算機,可是不少國家用的不是英文,他們的字母裏有許可能是ASCII裏沒有的,爲了能夠在計算機保存他們的文字,他們決定採用 127號以後的空位來表示這些新的字母、符號,還加入了不少畫表格時須要用下到的橫線、豎線、交叉等形狀,一直把序號編到了最後一個狀態255。從128 到255這一頁的字符集被稱」擴展字符集「。今後以後,貪婪的人類再沒有新的狀態能夠用了,美帝國主義可能沒有想到還有第三世界國家的人們也但願能夠用到計算機吧!

等中國人們獲得計算機時,已經沒有能夠利用的字節狀態來表示漢字,何況有6000多個經常使用漢字須要保存呢。可是這難不倒智慧的中國人民,咱們不客氣地把那些127號以後的奇異符號們直接取消掉, 規定:一個小於127的字符的意義與原來相同,但兩個大於127的字符連在一塊兒時,就表示一個漢字,前面的一個字節(他稱之爲高字節)從0xA1用到 0xF7,後面一個字節(低字節)從0xA1到0xFE,這樣咱們就能夠組合出大約7000多個簡體漢字了。在這些編碼裏,咱們還把數學符號、羅馬希臘的字母、日文的假名們都編進去了,連在 ASCII 裏原本就有的數字、標點、字母都通通從新編了兩個字節長的編碼,這就是常說的」全角」字符,而原來在127號如下的那些就叫」半角」字符了。 中國人民看到這樣很不錯,因而就把這種漢字方案叫作 「GB2312「。GB2312 是對 ASCII 的中文擴展。

可是中國的漢字太多了,咱們很快就就發現有許多人的人名沒有辦法在這裏打出來,特別是某些很會麻煩別人的國家領導人。因而咱們不得不繼續把 GB2312 沒有用到的碼位找出來老實不客氣地用上。 後來仍是不夠用,因而乾脆再也不要求低字節必定是127號以後的內碼,只要第一個字節是大於127就固定表示這是一個漢字的開始,無論後面跟的是否是擴展字符集裏的內容。結果擴展以後的編碼方案被稱爲 GBK 標準,GBK包括了GB2312 的全部內容,同時又增長了近20000個新的漢字(包括繁體字)和符號。 後來少數民族也要用電腦了,因而咱們再擴展,又加了幾千個新的少數民族的字,GBK擴成了 GB18030。今後以後,中華民族的文化就能夠在計算機時代中傳承了。 中國的程序員們看到這一系列漢字編碼的標準是好的,因而通稱他們叫作 「DBCS「(Double Byte Charecter Set 雙字節字符集)。在DBCS系列標準裏,最大的特色是兩字節長的漢字字符和一字節長的英文字符並存於同一套編碼方案裏,所以他們寫的程序爲了支持中文處理,必需要注意字串裏的每個字節的值,若是這個值是大於127的,那麼就認爲一個雙字節字符集裏的字符出現了。那時候凡是受過加持,會編程的計算機僧侶 們都要天天念下面這個咒語數百遍: 「一個漢字算兩個英文字符!一個漢字算兩個英文字符……」

由於當時各個國家都像中國這樣搞出一套本身的編碼標準,結果互相之間誰也不懂誰的編碼,誰也不支持別人的編碼,連大陸和臺灣這樣只相隔了150海里,使用着同一種語言的兄弟地區,也分別採用了不一樣的 DBCS 編碼方案——當時的中國人想讓電腦顯示漢字,就必須裝上一個」漢字系統」,專門用來處理漢字的顯示、輸入的問題,可是那個臺灣的愚昧封建人士寫的算命程序就必須加裝另外一套支持 BIG5 編碼的什麼」倚天漢字系統」才能夠用,裝錯了字符系統,顯示就會亂了套!這怎麼辦?並且世界民族之林中還有那些一時用不上電腦的窮苦人民,他們的文字又怎麼辦? 真是計算機的巴比倫塔命題啊!

正在這時,大天使加百列及時出現了——一個叫 ISO (國際標誰化組織)的國際組織決定着手解決這個問題。他們採用的方法很簡單:廢了全部的地區性編碼方案,從新搞一個包括了地球上全部文化、全部字母和符號 的編碼!他們打算叫它」Universal Multiple-Octet Coded Character Set」,簡稱 UCS, 俗稱 「unicode「。
unicode開始制訂時,計算機的存儲器容量極大地發展了,空間不再成爲問題了。因而 ISO 就直接規定必須用兩個字節,也就是16位來統一表示全部的字符,對於ASCII裏的那些「半角」字符,unicode包持其原編碼不變,只是將其長度由原來的8位擴展爲16位,而其餘文化和語言的字符則所有從新統一編碼。因爲」半角」英文符號只須要用到低8位,因此其高8位永遠是0,所以這種大氣的方案在保存英文文本時會多浪費一倍的空間。

這時候,從舊社會裏走過來的程序員開始發現一個奇怪的現象:他們的strlen函數靠不住了,一個漢字再也不是至關於兩個字符了,而是一個!是的,從unicode開始,不管是半角的英文字母,仍是全角的漢字,它們都是統一的」一個字符「!同時,也都是統一的」兩個字節「,請注意」字符」和」字節」兩個術語的不一樣,「字節」是一個8位的物理存貯單元,而「字符」則是一個文化相關的符號。在unicode中,一個字符就是兩個字節。一個漢字算兩個英文字符的時代已經快過去了。

unicode一樣也不完美,這裏就有兩個的問題,一個是,如何才能區別unicode和ascii?計算機怎麼知道三個字節表示一個符號,而不是分別表示三個符號呢?第二個問題是,咱們已經知道,英文字母只用一個字節表示就夠了,若是unicode統一規定,每一個符號用三個或四個字節表示,那麼每一個英文字母前都必然有二到三個字節是0,這對於存儲空間來講是極大的浪費,文本文件的大小會所以大出二三倍,這是難以接受的。

unicode在很長一段時間內沒法推廣,直到互聯網的出現,爲解決unicode如何在網絡上傳輸的問題,因而面向傳輸的衆多 UTF(UCS Transfer Format)標準出現了,顧名思義,UTF-8就是每次8個位傳輸數據,而UTF-16就是每次16個位。UTF-8就是在互聯網上使用最廣的一種unicode的實現方式,這是爲傳輸而設計的編碼,並使編碼無國界,這樣就能夠顯示全世界上全部文化的字符了。

UTF-8最大的一個特色,就是它是一種變長的編碼方式。它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度,當字符在ASCII碼的範圍時,就用一個字節表示,保留了ASCII字符一個字節的編碼作爲它的一部分,注意的是unicode一箇中文字符佔2個字節,而UTF-8一箇中文字符佔3個字節)。從unicode到uft-8並非直接的對應,而是要過一些算法和規則來轉換。

Unicode符號範圍 | UTF-8編碼方式

(十六進制) | (二進制)
—————————————————————–
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

 

Notice: 不管是UTF-8,UTF-16,仍是UTF-32,亦或者是UCS-2,UCS-4都是屬於Unicode.

Unicode和多字節(Multi-byte):

計算機中的字符並非保存爲圖像,每一個字符都是經過一個編碼來表示,而每一個字符究竟使用哪一個編碼表示,取決於所使用的字符集(charset)

在最初的時候世界上只有一種字符集-ASCII字符集,它使用7bits表示一個字符,總共能夠表示128個字符,以後又進行擴展使用8bits表示一個字符,總共能夠表示256個字符。

到了後來計算機再各個國家開始被應用ASCII顯然不能知足其餘國家需求。因而各個國家在ASCII標準上制定本身的字符集,這些從ASCII標準上派生出來的字符集一般被稱爲ASCII字符集,他們的正式名字應該是MBCS(Multi-byte-character-system)。這些派生字符集的特色是他們使用大於128的作爲一個Leading byte,和緊跟在Leading byte後面的第二個(甚至第三個)byte共同組成一個世紀的字符編碼.好比咱們國家的GB-2312.

例如在GB-2312字符集中,「連通」的編碼爲C1 AC CD A8,其中C1和CD就是Leading Byte。前127個編碼爲標準ASCII保留;

例如’0‘的編碼是30H(30H表示十六進制的30)。軟件在讀取時,若是看到30H,知道它小於128就是標準ASCII,表示「0」,看到C1大於128就知道它後面還有另外的編碼,所以C1 AC一同構成一個整個的編碼,在GB-2312字符集中表示「連」。

因爲每種語言都制定了本身的字符集,致使最後存在的各類字符集實在太多,在國際交流中要常常轉換字符集很是不便。所以,提出了Unicode字符集,它固定使用16 bits(兩個字節、一個字)來表示一個字符,共能夠表示65536個字符。將世界上幾乎全部語言的經常使用字符收錄其中,方便了信息交流。標準的Unicode稱爲UTF-16。後來爲了雙字節的Unicode可以在現存的處理單字節的系統上正確傳輸,出現了UTF-8,使用相似MBCS的方式對Unicode進行編碼。注意UTF-8是編碼,它屬於Unicode字符集。Unicode字符集有多種編碼形式,而ASCII只有一種,大多數MBCS(包括GB-2312)也只有一種。Unicode的最初目標,是用1個16位的編碼來爲超過65000字符提供映射。但這還不夠,它不能覆蓋所有歷史上的文字,也不能解決傳輸的問題 (implantation head-ache's),尤爲在那些基於網絡的應用中。已有的軟件必須作大量的工做來處理16位的數據

所以,Unicode用一些基本的保留字符制定了三套編碼方式它們分別是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列來編碼的,用一個或幾個字節(byte)來表示一個字符。這種方式的最大好處是:UTF-8保留了ASCII字符的編碼作爲它的一部分。例如,在UTF-8和ASCII中,‘A'的編碼都是0x41。  UTF-16和UTF-32分別是Unicode的16位和32位編碼方式。考慮到最初的目的,一般說的Unicode就是指UTF-16。

Notice: 對於UTF-16和UTF-32會在完整的字符序列一開始放一個byte order mark(BOM),用於標示它使用的是big-endian(此爲默認)仍是little-endian.

Big-endian和Little-endian:
Big endian和Little endian是CPU處理多字節數的不一樣方式。例如「漢」字的Unicode編碼是6C 49。那麼寫到文件裏時,到底是將6C寫在前面,仍是將49寫在前面?若是將6C寫在前面,就是Big endian。仍是將49寫在前面,就是Little endian。
「endian」這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開仍是從小頭(Little-Endian)敲開,由此曾發生過六次叛亂,其中一個皇帝送了命,另外一個丟了王位.

 

當一個軟件打開一個文檔的時候首先要肯定該文檔所用的字符集是什麼,下面的這種插入字符集標識的方法稱爲BOM:

1,若是是UTF-8會在文檔的開頭插入一個不顯示的字符:EF BB BF

2,若是是UTF-16/UCS-2(Big-endian)會在文檔的開頭插入一個不可見的字符:FE FF

     若是是UTF-16/UCS-2(Little-endian)會在文檔的開頭插入一個不可見的字符:FF FE

3,若是是UTF-32/UCS-4(Big-endian)會在文檔的開頭插入一個不可見的字符:FE FF 00 00

     若是是UTF-32/UCS-4(Little-endian)會在文檔的開頭插入一個不可見的字符:00 00 FF FE

4,若是是GB,GBK是不會插入任何標誌所以程序只能靠蒙.

 

           <-----------------------------------我是分割線---------------------------------------->

                      咱們已經瞭解了這麼多編碼了下面開始程序相關了:

在C/C++中咱們必須明確兩個概念:

源碼字符集(The source character set)     源碼文件是使用哪一種字符集保存的
執行字符集(The excution character set) 執行程序時候內存中的字符編碼

 

源文件字符集如何設置? 正如前面介紹的經過在文件開頭插入一個標誌
執行字符集如何設置? C++是經過設置std::locale

 

注意若是是MSVS2015若是源文件字符集被使用utf那麼程序的執行字符集也被默認使用utf8!

不須要再手動設置std::locale了.

也就是說:

//source.cpp  Notice:該cpp文件已經被用utf-8(BOM)的方式保存.

#include <iostream>

int main()
{
   std::basic_string<char> str("十花");  //這兩個字符串實際上是一致的.不管用不用u8標識.
   std::basic_string<char> str(u8"十花");
    
   return 0;

}
相關文章
相關標籤/搜索