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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Visual studio 与字符编码浅析

發布時間:2024/3/12 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Visual studio 与字符编码浅析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:https://blog.csdn.net/liangbch/article/details/79608635

關于字符編碼
1. 西方文字的編碼。

1.1 ASCII 碼,ASCII是通用的英文字符的編碼,對于英文字符,他采用7位2進制數來表示一個英文字符,我們知道1個byte包含8個bit,對于ASCII碼來說,最高bit為0.

1.2 ISO 8859,西方廣泛使用的編碼標準。用于西方文字,有256個碼位,前128個與ASCII標準兼容,后128個用于表示歐洲文字中的其他字母。

1.3 當然含有其他各種各樣的編碼,這里略去不談。

2. 中文和東方文字的編碼

2.1. GB 2312-1980。
這個標準由中國國家標準總局1980年發布的。 共收入漢字6763個和非漢字圖形字符682個.每個漢字由2個字節表示,第一個字節的范圍是0xa1-0xfe,第二個字節的范圍也是0xa1-0xfe,其編碼空間為94*94=8836。但實際上,并非編碼空間的每個字符都有定義。6763+682=7445<8836

2.2.GBK
GBK亦采用雙字節表示,是對GB2312的擴充。第1個字節的范圍是0x81-0xfe,第2個字節的范圍也是0x40-0xfe,剔除 xx7F一條線,即第2個字節不能是0x7f。總計23940 個碼位,共收入漢字21003個、符號883個,并提供1894個造字碼位,簡、繁體字融于一庫。中文Windows3.2和蘋果OS以GB2312為基本漢字編碼.

2.3. GB18030?
GB18030 有兩個標準,GB18030-2000 和GB18030-2005,可看做GBK的擴展。標準采用單字節、雙字節和四字節三種方式對字符編碼。編碼空間更大,當然也更復雜。

2.4.GB13000
GB13000有2個版本,為1993版和2010版. GB13000.1-1993 是1993年發布的,國際正式的叫法是ISO/IEC 10646。包含20902個漢字。這里解釋下漢字字符集。GB2312規定的6763個常用漢字可稱為漢字基本集。后期陸續增加了6個輔助集。這7個漢字集包含了所有的漢字,包括簡體漢字,繁體漢字,中日韓統一(CJK)漢字,總共包含了大約4萬9千個漢字,其中20902個漢字被GB13000.1-1993版定義。GB13000標準是一個宏大的標準,按其定義,總編碼位置高達2,147,483,648個。

2.5.UNICODE。UNICODE是由一個多語言軟件制造商組成的統一碼聯盟制定的標準,和ISO這個組織不同,這個標準試圖將不同的國家的語言統一到一個標準中。UNICODE有多種不同的編碼方式,包括UTF-8,UTF-16,UTF-32等。其中UTF-8,UTF-16最為常用。在Visual studio 中,如果宏UNICODE被定義,則字符串用UTF-16表示。對于UTF16編碼,所有的英文字符和漢字都用2個字節來表示。對于英文字符,高8位為0. 對于UTF-8編碼來說,英文字符仍用8比特表示,兼容ASCII,漢字則采用3字節來表示。

關于文本文件的格式

在中文Windows,你如果用記事本創建一個文件,點擊“另存為”菜單,你會發現,有一個編碼選項,可選擇編碼類型。見下圖

編碼類型的默認值是ANSI,其他的選項為 unicode, unicode big endian和utf-8. 其中ANSI意味著英文字符用ASCII的格式存儲,中文字符的編碼格式是GB2312。 中文windows默認的代碼頁是936.在命令行窗口輸入命令"MODE CON CP"可顯示你的windows的代碼頁設置。因為GB2312的代碼頁是936,所以ANSI格式的編碼即GB2312編碼。unicode意味著所有字符均使用2字節的形式來存儲,utf-8意味著,英文字符采用1字節來存儲,漢字采用3字節老存儲。對于ANSI編碼格式,文件內容不包括格式標識。對于其他編碼格式,文件頭部有2到3個字節的標記。具體為:

utf8:??????頭部標識為 0xef, 0xbb, 0xbf。
unicode :?頭部標識為 0xff, 0xfe.??對于英文字符,第1字節為其ASCII碼。第2字節為0.
unicode big endiam :??頭部標識為0xfe, 0xff. 對于英文字符,第1字節為0,第2字節為其ASCII碼。

Visual studio 源程序的編碼類型
Visual Stuio 2013 支持的編碼類型多達100多種。如果你點擊"文件"->"高級保存選項",你可以選擇各種各樣的編碼格式,見下圖。其中"UTF-8 帶簽名"指文件頭部有格式標識,"無簽名"指文件頭部沒有格式標識。

Visual C++ 與unicode
Visual C++ 工程文件有一個很重要的屬性,字符集,可設為"使用UNICODE字符集" 或"使用多字節字符集", 當設置為前者,工程文件中增加宏定義“_UNICODE”和"UNICODE". 當設置為使用多字節字符集,工程文件中增加宏定義“_MBCS", 是否有UNICODE這個宏對Windows API 函數的調用有很大的影響。事實上,Win32 API實際上有兩個版本。一個版本接受MBCS字符串,另一個接受Unicode字符串。例如:其實根本沒有SetWindowText()這個API函數,相反,真實的函數是SetWindowTextA()和SetWindowTextW()。后綴A表明這是MBCS函數,后綴W表示這是Unicode版本的函數。當UNICODE被定義,所有的函數并被替換成W結尾的函數,否則,函數被替換成A結尾的函數。下面例子來自winuser.h中的SetWindowText()函數的聲明部分:

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE  
可見,API函數根據定義UNICODE與否決定指向Unicode版本還是MBCS版本。

“UNICODE" 不但影響Windows API 函數的調用,也影響的C++/C運行時刻庫中部分函數的調用。實際上,關于字符串的C/C++函數也有2套版本,接收ANSI字符串格式的版本,和接收UNICODE字符串格式的版本。如printf 可接受ANSI字符串,而wprintf則接受UNICODE字符串的版本。他們的參數類型也相同,前者的字符串地址的類型是"char *",后者字符串地址的類型是"wchar_t *". 為了簡化編程,即使用同樣的源代碼,編譯為使用UNICODE字符集的版本和使用使用多字節字符集的版本。VC 中定義也一個tchar.h的頭文件。當"_UNICODE"未被定義(或_MBCS被定義)時,????宏"_TCHAR" 被定義為 "char",??宏"_T"被定義為空,在編譯時被預處理移除。當"_UNICODE"被定義時,"_TCHAR" 被定為為"wchar_t", 而"_T" 則被替換為"L", "L"的作用是將后面的字符或字符串轉換成相應的Unicode 形式。

?

下面的代碼顯示了,當UNICODE被定義和沒有定義時。程序的行為。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <tchar.h>
#include <locale.h>
?
void dump_buff(_TCHAR ?*buff, int len)
{
?? ?printf("buff[]=\n{");
?? ?for (int i = 0; i < len; i++)
?? ?{
#ifdef _UNICODE
?? ??? ?printf("0x%04X,", (_TUCHAR)buff[i]);
#else
?? ??? ?printf("0x%02X,", (_TUCHAR)buff[i]);
#endif
?? ?}
?? ?printf("}\n");
}
?
?
int main(int argc, char* argv[])
{
?? ?_TCHAR ?buff[20];
?? ?memset(buff, 0, sizeof(buff));
?? ?dump_buff(buff, sizeof(buff) / sizeof(_TCHAR));
?
#ifdef _UNICODE
?? ?setlocale(LC_CTYPE, "");?? ?//去掉這句,wprintf 不顯示任何輸出
?? ?wcscpy(buff, _T("你好,世界\n"));
?? ?wprintf(buff);
#else
?? ?strcpy(buff, _T("你好,世界\n"));
?? ?printf(buff);
#endif
?
?
?? ?dump_buff(buff, sizeof(buff) / sizeof(_TCHAR));
?? ?return 0;
}
當工程的屬性設為“使用UNICODE字符集”,程序輸出如下

buff[]=
{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000
0,0x0000,}
你好,世界
buff[]=
{0x4F60,0x597D,0x002C,0x4E16,0x754C,0x000A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000
0,0x0000,}
當工程的屬性設為”使用多字節字符集”時,程序輸出如下
buff[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
你好,世界
buff[]=
{0xC4,0xE3,0xBA,0xC3,0x2C,0xCA,0xC0,0xBD,0xE7,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
值得注意的是,當使用wprintf是,必須調用"setlocale(LC_CTYPE,"");" 否則這個函數不工作,更多的詳情,請參閱https://www.cnblogs.com/findumars/p/6147442.html?

編譯器對字符串的解釋
不管你的VC++源程序文件是以ANSI格式保存的,還是以UTF-8格式保存的,VC++編譯器總是把一個字符串解釋為ANSI格式的字符串。這看起來沒有問題。但是如果你想讓你的程序跨平臺,這就有問題了。Qt 可編寫跨平臺的代碼,即源代碼不需修改或者只做很小的調整,就可以編譯成運行在windows,linux或者Andriod平臺上的目標程序。如果程序需要顯示或者輸出英文以外的文字,最方便的編碼就是utf-8.??如果你的Qt 使用MinGW編譯,且將Qt工程中的源代碼文件的編碼設為UTF-8. 那么,輸出沒有問題,也不會遭遇到亂碼問題。但是,如果你的Qt使用Visual studio 作為編譯器.??將默認編碼設為"UTF-8",并將"UTF-8 BOM"設為"如果編碼是UTF-8則添加"。見下圖。

用Qt編寫的文件可用Visual Studio正確打開,但是在運行時則會顯示亂碼。這是因為VC的編譯器總是將字符串解釋為ANSI格式的字符串,即使源文件的編碼是UTF-8也不例外。但是Qt的程序需要將字符串解釋為UTF-8編碼的字符串。為此,需要在源文件開頭添加如下編譯指示。加上這句話。Qt的程序就能正確工作了

#pragma execution_character_set("utf-8")
————————————————
?

總結

以上是生活随笔為你收集整理的Visual studio 与字符编码浅析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。