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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++汉字字符处理

發(fā)布時(shí)間:2023/12/20 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++汉字字符处理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問題:實(shí)現(xiàn)Apriori算法時(shí)的數(shù)據(jù)集為中文,所以需要用到漢字字符處理。現(xiàn)搜集整合如下。

#include <stdio.h> void main(void){char str[100];printf("輸入漢字:\n");scanf("%s",str);printf("%c%c %c%c\n", str[0],str[1],str[2],str[3]); printf("%s\n",str); }

測(cè)試結(jié)果:


  • 轉(zhuǎn)載1 關(guān)于C中文字符的處理
    • 一 引入問題
    • 二 解決引入問題所需的知識(shí)
    • 三 漢字的編碼方式及在vcc中的處理
      • 漢字編碼方式的介紹
      • vc中漢字的編碼方式
      • 新的內(nèi)碼標(biāo)準(zhǔn)Unicode
      • 內(nèi)碼的相互轉(zhuǎn)換
    • 四 vc中的MutiByte Charater Set 和 Wide Character Set
      • MultiByte Charater Set方式
      • Wide Character Set
    • 五 引入問題的錯(cuò)誤分析
  • 轉(zhuǎn)載2 C讀寫漢字C處理中文字符
  • 擴(kuò)展1 unicode-ansi-utf-8-unicode-big-endian編碼的區(qū)別
  • 擴(kuò)展2 各種字符集編碼
  • 擴(kuò)展3 Unicode 和 UTF-8 有何區(qū)別知乎


轉(zhuǎn)載1 關(guān)于C++中文字符的處理

一 引入問題

代碼 wchar_t a3=L”中國(guó)”,編譯時(shí)出錯(cuò),出錯(cuò)信息為:數(shù)組越界。但wchar_t 是一個(gè)寬字節(jié)類型,數(shù)組a的大小應(yīng)為6個(gè)字節(jié),而兩個(gè)漢字的的unicode碼占4個(gè)字節(jié),再加上一個(gè)結(jié)束符,最多6個(gè)字節(jié),所以應(yīng)該不會(huì)越界。難道是編譯器出問題了?

二 解決引入問題所需的知識(shí)

? ? ? ?主要需兩方面的知識(shí)
1. 字符尤其是漢字的編碼,以及語言和工具的支持情況
2. vc/c++中MutiByte Charater Set 和 Wide Character Set有關(guān)內(nèi)存分配的情況.

三 漢字的編碼方式及在vc/c++中的處理

1.漢字編碼方式的介紹

? ? ? ?對(duì)英文字符的處理,7位ASCII碼字符集中的字符即可滿足使用需求,且英文字符在計(jì)算機(jī)上的輸入及輸出也非常簡(jiǎn)單,因此,英文字符的輸入、存儲(chǔ)、內(nèi)部處理和輸出都可以只用同一個(gè)編碼(如ASCII碼)。
? ? ? ?而漢字是一種象形文字,字?jǐn)?shù)極多(現(xiàn)代漢字中僅常用字就有六、七千個(gè),總字?jǐn)?shù)高達(dá)5萬個(gè)以上),且字形復(fù)雜,每一個(gè)漢字都有”音、形、義”三要素,同音字、異體字也很多,這些都給漢字的的計(jì)算機(jī)處理帶來了很大的困難。要在計(jì)算機(jī)中處理漢字,必須解決以下幾個(gè)問題:首先是漢字的輸入,即如何把結(jié)構(gòu)復(fù)雜的方塊漢字輸入到計(jì)算機(jī)中去,這是漢字處理的關(guān)鍵;其次,漢字在計(jì)算機(jī)內(nèi)如何表示和存儲(chǔ)?如何與西文兼容?最后,如何將漢字的處理結(jié)果從計(jì)算機(jī)內(nèi)輸出?
? ? ? ?為此,必須將漢字代碼化,即對(duì)漢字進(jìn)行編碼。對(duì)應(yīng)于上述漢字處理過程中的輸入、內(nèi)部處理及輸出這三個(gè)主要環(huán)節(jié),流程如下:

Created with Rapha?l 2.1.0輸入輸入碼交換碼內(nèi)部碼字形碼輸出

(1) 輸入碼
? ? ? ?作用是,利用它和現(xiàn)有的標(biāo)準(zhǔn)西文鍵盤結(jié)合來輸入漢字。輸入碼也稱為外碼。主要?dú)w為四類:

  • 數(shù)字編碼
    數(shù)字編碼是用等長(zhǎng)的數(shù)字串為漢字逐一編號(hào),以這個(gè)編號(hào)作為漢字的輸入碼。例如,區(qū)位碼、電報(bào)碼等都屬于數(shù)字編碼。

  • 拼音碼
    拼音碼是以漢字的讀音為基礎(chǔ)的輸入辦法。

  • 字形碼
    字形碼是以漢字的字形結(jié)構(gòu)為基礎(chǔ)的輸入編碼。例如,五筆字型碼(王碼)。

  • 音形碼
    音形碼是兼顧漢字的讀音和字形的輸入編碼。

(2) 交換碼
? ? ? ?用于漢字外碼和內(nèi)部碼的交換。交換碼的國(guó)家標(biāo)準(zhǔn)代號(hào)為GB2312-8090。

(3) 內(nèi)部碼
? ? ? ?內(nèi)部碼是漢字在計(jì)算機(jī)內(nèi)的基本表示形式,是計(jì)算機(jī)對(duì)漢字進(jìn)行識(shí)別、存儲(chǔ)、處理和傳輸所用的編碼。內(nèi)部碼也是雙字節(jié)編碼,將國(guó)標(biāo)碼兩個(gè)字節(jié)的最高位都置為”1”,即轉(zhuǎn)換成漢字的內(nèi)部碼。

(4) 字形碼
? ? ? ?字形碼是表示漢字字形信息(漢字的結(jié)構(gòu)、形狀、筆劃等)的編碼,用來實(shí)現(xiàn)計(jì)算機(jī)對(duì)漢字的輸出(顯示、打印)。

2.vc中漢字的編碼方式

? ? ? ?vc/c++正是采用了GB2312內(nèi)部碼作為漢字的編碼方式,因此vc/c++中的各種輸入輸出方法,如cin/wcin,cout/wcout,scanf/wsanf,printf/wprintf…都是基于GB2312的,如果漢字的內(nèi)碼不是這種編碼方式,那么利用上述各種方法就不會(huì)正確的解析漢字。

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH33!65A97a
2STX3466B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104
9HT41)73I105
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL
? ? ? ?? ? ?NUL空? ? ? ?? ? ?VT 垂直制表? ? ? ?? SYN 空轉(zhuǎn)同步
STX 正文開始CR 回車CAN 作廢
ETX 正文結(jié)束SO 移位輸出EM 紙盡
EOY 傳輸結(jié)束SI 移位輸入SUB 換置
ENQ 詢問字符DLE 空格ESC 換碼
ACK 承認(rèn)DC1 設(shè)備控制1FS 文字分隔符
BEL 報(bào)警DC2 設(shè)備控制2GS 組分隔符
BS 退一格DC3 設(shè)備控制3RS 記錄分隔符
HT 橫向列表DC4 設(shè)備控制4US 單元分隔符
LF 換行NAK 否定DEL 刪除

? ? ? ?仔細(xì)觀察ASCII字符表,從第161個(gè)字符開始,后面的字符并不經(jīng)常為用戶所使用,負(fù)值也未使用。GB2312編碼方式充分利用這一特性,將161-255(-95~-1)之間的數(shù)值空間作為漢字的標(biāo)識(shí)碼。既然255-161 = 94不能滿足漢字容量的要求,就將每?jī)蓚€(gè)字符并在一塊(即一個(gè)漢字占兩個(gè)字節(jié)),顯然,94* 94 =8836基本上已經(jīng)滿足了常用漢字個(gè)數(shù)的要求。計(jì)算機(jī)處理字符時(shí),當(dāng)連續(xù)處理到兩個(gè)大與160(或-95~-1)的字節(jié)時(shí),就認(rèn)為這兩個(gè)字節(jié)存放了一個(gè)漢字字符。可以用下面的Demo程序來模擬vc/c++中輸出漢字字符的過程。

unsigned char input[50]; cin>>input;int flag=0;for(int i =0 ;i < 50 ;i++){if(input[i] > 0xa0 && input[i] != 0){if(flag == 1){cout<<"chinese character"<flag = 0;}else{flag++;//一字節(jié),前四位識(shí)別,后四位確定并輸出,見上一段if程序}}else if(input[i] == 0){break;}else{cout<<"english character"<flag=0;} }

輸入:Hello中國(guó) (“中國(guó)”對(duì)應(yīng)的GB2312內(nèi)碼為:214 208,185 250)
輸出:english character
english character
english character
english character
english character
chinese character
chinese character

? ? ? ?vc/c++中的英文字符仍然采用ASCII編碼方式。可以設(shè)想,其他國(guó)家程序員利用vc/c++編寫程序輸入本國(guó)字符時(shí),vc/c++則會(huì)采用該國(guó)的字符編碼方式來處理這些字符。
? ? ? ? 問題又產(chǎn)生了,韓國(guó)的vc/c++程序在中國(guó)的vc/c++上運(yùn)行時(shí),如果沒有相應(yīng)的內(nèi)碼庫(kù),則對(duì)韓語字符的顯示有可能出現(xiàn)亂碼。我個(gè)人猜測(cè),vc安裝程序中應(yīng)該帶有不同國(guó)家的內(nèi)碼庫(kù),這樣一來肯定會(huì)占用很大的空間。如果所有的國(guó)家使用統(tǒng)一的編碼方式,且所有的程序設(shè)計(jì)語言和開發(fā)工具都支持這種編碼方式該多好!而現(xiàn)實(shí)中,確實(shí)已經(jīng)有這種編碼方式了,且許多新的語言也都支持這種編碼方式,如Java、C#等,它就是下面的Unicode編碼

3.新的內(nèi)碼標(biāo)準(zhǔn)—Unicode

? ? ? ?Unicode(統(tǒng)一碼、萬國(guó)碼、單一碼)是一種在計(jì)算機(jī)上使用的字符編碼。它為每種語言中的每個(gè)字符設(shè)定了統(tǒng)一并且唯一的二進(jìn)制編碼,以滿足跨語言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求。
? ? ? ?在Unicode 5.0.0版本中,已定義的碼位只有238605個(gè),分布在平面0、平面1、平面2、平面14、平面15、平面16。其中平面15和平面16上只是定義了兩個(gè)各占65534個(gè)碼位的專用區(qū)(Private Use Area),分別是0xF0000-0xFFFFD和0x100000-0x10FFFD。所謂專用區(qū),就是保留給大家放自定義字符的區(qū)域,可以簡(jiǎn)寫為PUA。
? ? ? ?平面0也有一個(gè)專用區(qū):0xE000-0xF8FF,有6400個(gè)碼位。平面0的0xD800-0xDFFF,共2048個(gè)碼位,是一個(gè)被稱作代理區(qū)(Surrogate)的特殊區(qū)域。代理區(qū)的目的用兩個(gè)UTF-16字符表示BMP以外的字符。在介紹UTF-16編碼時(shí)會(huì)介紹。
? ? ? ?如前所述在Unicode 5.0.0版本中,238605-65534*2-6400-2048=99089。余下的99089個(gè)已定義碼位分布在平面0、平面1、平面2和平面14上,它們對(duì)應(yīng)著Unicode定義的99089個(gè)字符,其中包括71226個(gè)漢字。平面0、平面1、平面2和平面14上分別定義了52080、3419、43253和337個(gè)字符。平面2的43253個(gè)字符都是漢字。平面0上定義了27973個(gè)漢字。
? ? ? ?在Unicode中:漢字“字”對(duì)應(yīng)的數(shù)字是23383(十進(jìn)制),十六進(jìn)制表示為5B57。在Unicode中,我們有很多方式將數(shù)字23383表示成程序中的數(shù)據(jù),包括:UTF-8、UTF-16、UTF-32。UTF是“Unicode Transformation Format”的縮寫,可以翻譯成Unicode字符集轉(zhuǎn)換格式,即怎樣將Unicode定義的數(shù)字轉(zhuǎn)換成程序數(shù)據(jù)。
? ? ? ?例如,“漢字”對(duì)應(yīng)的數(shù)字是0x6c49和0x5b57,而編碼的程序數(shù)據(jù)是:

char data_utf8[]={0xE6,0xB1,0x89,0xE5,0xAD,0x97};//UTF-8編碼 char16_t data_utf16[]={0x6C49,0x5B57}; //UTF-16編碼 char32_t data_utf32[]={0x00006C49,0x00005B57};//UTF-32編碼

? ? ? ?這里用char、char16_t、char32_t分別表示無符號(hào)8位整數(shù),無符號(hào)16位整數(shù)和無符號(hào)32位整數(shù)。UTF-8、UTF-16、UTF-32分別以char、char16_t、char32_t作為編碼單位。(注: char16_t 和 char32_t 是 C++ 11 標(biāo)準(zhǔn)新增的關(guān)鍵字。如果你的編譯器不支持 C++ 11 標(biāo)準(zhǔn),請(qǐng)改用 unsigned short 和 unsigned long。)“漢字”的UTF-8編碼需要6個(gè)字節(jié)。“漢字”的UTF-16編碼需要兩個(gè)char16_t,大小是4個(gè)字節(jié)。“漢字”的UTF-32編碼需要兩個(gè)char32_t,大小是8個(gè)字節(jié)。

? ? ? ?Unicode 編碼系統(tǒng)可分為編碼方式實(shí)現(xiàn)方式兩個(gè)層次。

  • 編碼方式(此文作于08年)
    ? ? ? ?Unicode 的編碼方式與 ISO 10646 的通用字符集(Universal Character Set,UCS)概念相對(duì)應(yīng),目前的用于實(shí)用的 Unicode 版本對(duì)應(yīng)于 UCS-2,使用16位的編碼空間。也就是每個(gè)字符占用2個(gè)字節(jié)。這樣理論上一共最多可以表示 216 個(gè)字符。基本滿足各種語言的使用。實(shí)際上目前版本的 Unicode 尚未填充滿這16位編碼,保留了大量空間作為特殊使用或?qū)頂U(kuò)展。

  • 實(shí)現(xiàn)方式
    ? ? ? ?Unicode 的實(shí)現(xiàn)方式不同于編碼方式。
    ? ? ? ?目前的Unicode字符分為17組編排,0x0000 至 0x10FFFF,每組稱為平面(Plane),而每平面擁有65536個(gè)碼位,共1114112個(gè)。
    ? ? ? ?一個(gè)字符的 Unicode 編碼是確定的。但是在實(shí)際傳輸過程中,由于不同系統(tǒng)平臺(tái)的設(shè)計(jì)不一定一致,以及出于節(jié)省空間的目的,對(duì) Unicode 編碼的實(shí)現(xiàn)方式有所不同。
    ? ? ? ?Unicode 的實(shí)現(xiàn)方式稱為Unicode轉(zhuǎn)換格式(Unicode Translation Format,簡(jiǎn)稱為 UTF)。如,UTF-8 編碼,這是一種變長(zhǎng)編碼,它將基本7位ASCII字符仍用7位編碼表示,占用一個(gè)字節(jié)(首位補(bǔ)0)。而遇到與其他 Unicode 字符混合的情況,將按一定算法轉(zhuǎn)換,每個(gè)字符使用1-3個(gè)字節(jié)編碼,并利用首位為0或1進(jìn)行識(shí)別。
    ? ? ? ?Java與C#語言都是采用Unicode編碼方式,在這兩種語言中定義一個(gè)字符,在內(nèi)存中存放的就是這個(gè)字符的兩字節(jié)Unicode碼。如下所示:
    ? ? ? ?char a=’我’; => 內(nèi)存中存放的Unicode碼為:25105

4.內(nèi)碼的相互轉(zhuǎn)換

(1) vc中的實(shí)現(xiàn)方法
? ? ? ?利用Windows系統(tǒng)提供的API:::MultiByteToWideChar和::WideCharToMultiByte
::MultiByteToWideChar:實(shí)現(xiàn)當(dāng)前碼到Unicode碼的轉(zhuǎn)換;
::WideCharToMultiByte:實(shí)現(xiàn)Unicode碼到當(dāng)前碼的轉(zhuǎn)換;

(2) Java中的實(shí)現(xiàn)方法
? ? ? ?String vcString=new String(javaString.getBytes(“UTF-8”),”gb2312”);
? ? ? ?java的編碼應(yīng)該是UTF-8

(3) C#中的實(shí)現(xiàn)方法
? ? ? ???

四 vc中的MutiByte Charater Set 和 Wide Character Set

1.MultiByte Charater Set方式

? ? ? ?這種方式以按字節(jié)為單位存放字符,即如果一個(gè)字符碼為兩字節(jié),則在內(nèi)存中占兩字節(jié),字符碼為一字節(jié),就占一字節(jié)。例如,字符串“中國(guó)abc”的編碼為:中(0xd6、0xd0)、國(guó)(0xb9、0xfa)、a(0x61)、b(0x62)、c(0x63)、\0(0x00),就存為如下方式:

? ? ? ?對(duì)應(yīng)的類型,方法有:char、scanf、printf、cin、cout …

2.Wide Character Set

? ? ? ?這種方式是以兩字節(jié)為單位存放字符,即如果一個(gè)字符碼為兩字節(jié),則在內(nèi)存中占四字節(jié),字符碼為一字節(jié),就占兩字節(jié)。例如,字符串“中國(guó)abc”就存為如下方式:

? ? ? ?對(duì)應(yīng)的類型,方法有:wchar_t、wscanf、wprintf、wcin、wcout …
? ? ? ?造成上面存儲(chǔ)方式的根本原因在于,wchar_t類型其實(shí)是一個(gè)unsigned short 類型。如,存儲(chǔ)上面字符串的數(shù)組的定義為:wchar_t buffer[8] 等價(jià)于unsigned short buffer[8].而所有以字母w開頭的方法也都是以u(píng)nsigned short類型,即兩字節(jié)為單位來處理字符,因此,存儲(chǔ)在wchar_t類型數(shù)組中的字符串無法用cout顯示,只能用wcout方法來顯示。
? ? ? ?由于Unicode碼也是采用兩個(gè)字節(jié),因此Wide Character Set方式能夠很好的支持Unicode碼的存儲(chǔ),但是在vc的環(huán)境下要將一個(gè)Unicode碼存入兩字節(jié)而不是四字節(jié)內(nèi)存中,必須通過上面的API函數(shù)::MultiByteToWideChar。首先,將當(dāng)前的編碼轉(zhuǎn)換為Unicode碼,然后,將每個(gè)字符的Unicode碼放入每一個(gè)wchar_t類型的變量中。以下是一個(gè)實(shí)例代碼:

char input[50]; cin>>input; int size; size=::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,NULL,0); if(size==0)return -1; wchar_t *widebuff=new wchar_t[size]; ::MultiByteToWideChar(CP_ACP,0,input,strlen(input)+1,widebuff,size);

輸入:中國(guó)abc
Debug斷點(diǎn)調(diào)試:
size==6

? ? ? ?數(shù)組widebuff[0-size]占12字節(jié),存放了6個(gè)字符的Unicode碼,碼值為:
? ? ? ?中(0x4e2d) 國(guó)(0x56fd) a(0x0061) b(0x0062) c(0x0063) d(0x0000)
? ? ? ?這時(shí),數(shù)組的大小size等于輸入的字符個(gè)數(shù)加上一個(gè)結(jié)束符,符合我們的想象。

五 引入問題的錯(cuò)誤分析

  • 沒有理解編譯器中的編碼方式
    ? ? ? ?雖然vc/c++中漢字的編碼占兩個(gè)字節(jié),但并不是Unicode碼,是GB2312碼。

  • 沒有理解MutiByte Charater Set 和 Wide Character Set的存儲(chǔ)原則;
    ? ? ? ?在vc/c++中,“中國(guó)”按char5來對(duì)待,而wchar_t a3實(shí)際上是三個(gè)unsigned short類型的變量,因此賦值時(shí)會(huì)越界。

  • 轉(zhuǎn)載2 C++讀寫漢字,C++處理中文字符

    擴(kuò)展1 unicode-ansi-utf-8-unicode-big-endian編碼的區(qū)別

    ????2010年上傳的文章,但是真的深入淺出,推薦。

    擴(kuò)展2 各種字符集編碼

    擴(kuò)展3 Unicode 和 UTF-8 有何區(qū)別?(知乎)

    總結(jié)

    以上是生活随笔為你收集整理的c++汉字字符处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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