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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC中的Unicode

發(fā)布時間:2025/3/21 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC中的Unicode 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

學習C語言的時候您應該接觸過ASCII碼。學習本章的內(nèi)容需要ASCII知識。

學習Unicode有必要了解字符集的歷史。從最早的象形字開始,我們使用字符文字已經(jīng)有近6000年了。19世紀的幾個發(fā)明家發(fā)明了電報,當時在電報中使用的代碼是Morse代碼。字母表中的每個字符對應于一系列短和長的脈沖。

計算機是處理的數(shù)據(jù)其實是一系列1和0。每一段數(shù)字都代表一種字符。這就是ASCII碼。7位數(shù)的ASCII碼對于美國的字符集支持得很好。不幸的是地球上有一百多個國家和地區(qū),2000多個民族。對于美國以外的用戶來講在計算機中顯示自己國家的文字困難重重。

尤其是中國,日本,朝鮮更是如此。以中國為例,有數(shù)也數(shù)不清的漢字。辦法總是有的。人們引入了"代碼頁"和"雙字節(jié)字符集"的概念。這種編碼方式非常龐大和復雜,不利于維護。這個時候Unicode應運而生了。

Unicode的解決方案非常簡單。既然不能用7位或者8位數(shù)值表示,那么我們應該試一下更寬的值。例如16位,這樣就允許表示65536個字符。Unicode和ASCII是兼容的。也就是說,前128個字符的數(shù)值是相同的。

Unicode的最大好處是只有一個字符集。當然Unicode也有缺點,Unicode占用的內(nèi)存是ASCII碼的兩倍。而且人們還不太習慣Unicode。

對于程序員來講,8位的ASCII碼和16位的Unicode是我們必須面對的問題。為了解決寬字符(16位)問題,Windows在頭文件中定義了"新"數(shù)據(jù)類型。

typedef?unsigned short?wchar_t;

可以看出wchar_t其實是16位的無符號短整型數(shù)。Windows用這種方法存貯16位字符。

wchar_t *p =?L"Hello!";

在"Hello!"前有一個大寫字母L(代表long)。這將告訴編譯器該字符串按寬字符保存。即每個字符占用2個字符。存貯該字符串需要14個字節(jié)。字符串末尾還有一個/0也需要2個字節(jié)。

我們都知道如何獲得字符串的長度。

int?iLength;
char?*pc = "Hello!";
iLength = strlen(pc);

函數(shù)strlen()返回字符串的長度,長度將不包括末尾的/0。變量iLength將等于6,也就是字符串中的字符數(shù)。

接下來我們試著用strlen()檢查寬字符的字符串。

wchar_t *pw = L"Hello!";
iLength = strlen(pw);

strlen()的參數(shù)應該是char類型的指針,但是現(xiàn)在卻接受了一個unsigned short類型的指針。編譯后您會發(fā)現(xiàn)iLength等于1。

why?字符串"Hello!"中的6個字符寬字符代碼如下:

0x0048 0x0065 0x006c 0x006c 0x006f 0x0021

Intel處理器在內(nèi)存中將其存為:

48 00 65 00 6c 00 6c 00 6f 00 21 00

strlen()的工作過程是遇到0就結(jié)束。因為0表示一個字符串的結(jié)束。當讀完"48"后strlen()遇到的是0,所以strlen()返回1。

由上例可以看出C語言的函數(shù)無法正確處理寬字符。在參數(shù)中有字符串的函數(shù)全部需要重寫。strlen()的寬字符版本是wcslen(),并且在STRING.H中和WCHAR.H中均有聲明.

現(xiàn)在我們知道,要得到寬字符串的長度,可以調(diào)用

iLength = wcslen(pw);

該函數(shù)返回將返回字符串中的字符數(shù)6。請記住,改成寬字節(jié)后字符串的字符長度不變,只是字節(jié)長度改變了。千萬不要混淆。

因為Unicode占用兩倍的存儲空間,所以寬字節(jié)運行庫中的函數(shù)比常規(guī)的函數(shù)大。所以最好是建立兩個版本的程序,一個處理ASCII字符串,另一個處理Unicode字符串。但是這樣以來又引來了另一個小問題。因為每一個實現(xiàn)特定功能的函數(shù)都有兩個版本,所以名字不好記。不管是ASCII版本還是Unicode版本,都用相同的名字該多好啊?幸好這個問題已經(jīng)得到了解決。

解決辦法是使用Visual C++包含的TCHAR.H頭文件。該頭文件不是標準C的一部分。為了與標準C的頭文件分別開來,該頭文件內(nèi)定義的每個函數(shù)和宏定義的前面都有一條下劃線。


TCHAR.H為需要字符串的標準運行庫函數(shù)提供了一系列的替代名稱。有時這些名稱被稱為"通用"函數(shù)名,因為它們既可以指向函數(shù)的Unicode版本,也可以指向ASCII版本。
以_tcslen()為例如果定義了_UNICODE的標識符,并且程序中包含了TCHAR.H,那么_tcslen()就定義為wcslen():

#define _tcslen wcslen

如果沒有定義_UNICODE,則_tcslen()被定義為strlen()。

#define _tcslen strlen

TCHAR.H還用一個新的數(shù)據(jù)類型TCHAR來解決兩種字符數(shù)據(jù)類型的問題。如果定義了_UNICODE標識符,那么TCHAR就是wchar_t:

typedef wchar_t TCHAR;

否則TCHAR就是char:

typedef char TCHAR;

還記得第一章里出現(xiàn)過的TEXT()嗎?那是為了兼容UNICODE字符集所做的改動。下面就來看看TEXT()在頭文件中是怎么定義的。

#define __T(x)??? L##x

后面的L##x您可能看不懂。很少有書提到它。但那確實是標準C預處理的一部分。這一對"##"稱為粘貼號(token paste)。看來我們對標準C的了解還不夠。是時候買本"The C Programming Language"了。它將字母L添加到宏參數(shù)上。

__T("Hello!") 等于 L##"Hello!" 等于 L"Hello!"。

此外還有兩個宏與__T定義相同:

#define _T(x) __T(x)
#define _TEXT(x) __T(x)

WINNT.H頭文件中還定義了一個宏,該宏也跟__T一樣,將L添加到字符串前。

#ifdef UNICODE
#define __TEXT(quote) L##quote
#else
#define __TEXT(quote) quote
#endif

#define TEXT(quote) __TEXT(quote)


轉(zhuǎn)載:http://www.cnblogs.com/Jessy/articles/1746337.html

轉(zhuǎn)載于:https://www.cnblogs.com/qhyuan1992/p/5385336.html

總結(jié)

以上是生活随笔為你收集整理的VC中的Unicode的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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