編碼知識
一、Unicode與多字節(ANSI )
(1)Windows中,Unicode也稱為寬字節,多字節也稱為窄字節; VS中默認使用Unicode編碼,在項目屬性>>配置屬性>>常規>>字符集中可選擇Unicode字符集或者多字節字符集
(2) Unicode與多字節函數版本、字符、字符串類型的區別
Win32 API中大部分參數有字符串的函數都有兩個版本
以A結尾,代表多字節版本 | 以W結尾,代表Unicode版本 | 根據版本自動選擇的 |
---|---|---|
如:CreateEventA | 如:CreateEventW | 如:CreateEvent |
C運行庫也有很多類似的函數
多字節版本 | Unicode版本 | 自適應版本 |
---|---|---|
strcpy | wcscpy | _tcscpy |
strcat | wcscat | _tscscat |
strlen | wcslen | _tcslen |
函數有兩種,所以字符也有兩種
多字節字符 | Unicode字符 | 自適應字符 |
---|---|---|
char | wchar_t | TCHAR |
(3) 常見Win32字符串類型
LPSTR、LPWSTR、LPTSTR、LPCTSTR
LP前綴,代表指針;STR后綴代表字符串
LPSTR:代表多字節
LPWSTR:代表Unicode
LPTSTR:T自適應
LPCTSTR:C代表const+T代表自適應
備注:變量類型使用自適應類型后如LPTSTR,相關字符串需要用TEXT()進行包裹
const char* str = "hello";
const wchar_t* wstr = L"hello";
const TCHAR* tstr = TEXT("hello");
(4)關於_T()
#ifdef _UNICODE
#define _T(X) L ## X //Unicode版本
#else
#define _T(X) X //多字節版本
#endif
(5)Unicode與多字節的選擇
1.Unicode程序環境適應能力強,不會出現亂碼問題
2.Unicode程序運行速度比多字節程序快。原因:Windows內部都是使用Unicode編碼,多字節函數會將參數轉碼后交給Unicode函數
3.控制后台可使用多字節,GUI程序最好使用Unicode
二、Unicode
(1)Unicode實現方式:UTF-32
以4個byte為編碼單元進行定長存儲,調度器一次性下發4個byte進行存儲任務
主要有兩種方式:
大端法UTF-32BE:地址由小向大增加,而數據從高位往低位放 ,在網絡上傳輸數據普遍采用的都是大端
小端法UTF-32LE:地址由小向大增加,而數據從低位往高位放,在英特爾處理器,Windows10操作系統,采用小端法。
(2)UTF-16
也有大小端模式
UTF-16 LE是windows上默認的Unicode編碼方式,使用wchar_t表示。所有wchar_t *類型的字符串(包括硬編碼在.h/.cpp里的字符串字面值)
char chinese[] = "你";
//大小為3個byte,一個char存儲結束符,兩個char存儲漢字字符‘你’ 1char:1byte
wchar_t wchinese[] = L"你";
//大小為4個byte, 一個wchar_t存儲結束符,一個wchar_t存儲漢字字符‘你’ 1wchar_t:2byte(window下)
auto size = sizeof(chinese); // 3 byte
auto wsize = sizeof(wchinese); // 4 byte
auto len = strlen(chinese); // 2個字符(除去結束符)
auto wlen = wcslen(wchinese); // 1個字符(除去結束符)
優勢:就是大多數情況下一個wchar_t表示一個字符(包括中文字符)
坑:char *類型的字面值,最終內存使用何種編碼方式完全取決於當前文件的編碼方式
備注:在Windows上應該銘記沒有char / std::string這種類型的字符/字符串,只有wchar_t / char16_t / std::wstring / std::u16string
(3)UTF-8
優勢:無字節序的概念,不用考慮大小端問題,適用與字符串的網絡數據傳輸
劣勢:如上代碼,一個char並不能表示一個漢字字符,往往需要兩個char
三、ANSI
(1)概念
可以認為ANSI / MBCS (多字節字符集) / 本地編碼是同一個概念,不同的國家和地區制定了不同的標准,有GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的編碼標准,ASCII就是美國國家的ANSI標准,一個國家的代碼到另一個國家使用,有可能由於編碼標准不一致,導致亂碼,於是才有了萬國碼Unicode,各國通用。