Win32API UNICODE編碼&寬字節
阿新 • • 發佈:2017-05-15
定義 自己 市場 計算機 數字 try type 文件 code
Win32API UNICODE編碼&寬字節
- 計算機是由於是美國人發明的,所以字符集先以英文為主。上世紀三十年代,滿足自己的編碼方式:ASC編碼方式,以7位(bit)代表一個字符,能表示的字符才128個。因為以前內存很貴。128個字符足夠美國人用的了。
- 計算機發展到歐洲,發現ASC是不夠用的。就發展為ASCII
- 歐洲有些國家是不用英文的:如西班牙等~~
- 升級ASCII後,用8位內存來表示字符編碼,有256個字符。如此前128個定下來永久不變,後面128個分配給歐洲其它語種。歐洲有十幾個國家,發現還是不夠用。美國人采取了一種折中辦法:在不增加內存的情況下,采取(CodePage)“代碼頁”的機制來表示字符編碼。用一個數字來表示一個語種:比如用936代碼漢語,或是用437代碼英語等。如果代碼頁是中文代碼頁,後128就是漢字。如果代碼頁437那麽後128就是英文。
- 記住ASCII的常用3個位置:
- 1 小寫a的ASCII編碼:97 ##助記:(眼鏡a),香港回歸
- 2 大寫A的ASCII編碼:65
- 3 阿拉伯數字0的ASCII編碼:48 ##助記:“盜聖,你的事發(48)了~~”&&香港回歸,建國48年(97-49)
- 又過了些年發展,計算機來到亞洲,(8bit) 256也是不夠用的。
- 就是說漢字,後128給我們是絕對不夠用的。就發展成DBCS(單雙字節混合編碼6萬多個字符),當前計算機的主流編碼方式。
- DBCS這種編碼先天具有缺陷,先天“小兒麻痹”,一個處理不當會產生亂碼。因為英文占一個字節,漢字占兩個字節,這個規定就不是唯一的,容易出錯。解析字符串的時候,要有兩種標準來分析字符串,處理就會先天的慢一些。
- 最後就出現了UNICODE編碼方式:可以認為是DBCS上的一個補丁,UNICODE統一規範:所有字符全部2個字符編碼,英文漢字全部一發切,能能按兩個字節來編碼。在英文高字節上補0.
- UNICODE編碼方式有個缺點:占用內存空間,有浪費的嫌疑,但以現在的硬件來看,已經不是問題了。但它並不是市場上主流的編碼方式。
- 字符集的應用
- char 有占用1個字節,有占用兩個字節 (DBCS編碼)
- 寬字節 wchar_t每個占用兩個字節 (UNICODE編碼)
- wchar_t實際是unsigned short類型(占用2個字節)
- 定義時需要增加“L”. 給編譯器看,通知編譯器按照雙字節編譯字符串。
- 需要使用支持wchar_t類型的函數,來操作寬字節字符串。
wchar_t* pwszText = L"Hello wchar";
wprintf(L"%s \n",pwszText);? - 這裏不能套用標準C中的char*的函數了,雙字節的操作一定要采用雙字節對應的函數來操作。
- windows中的新類型:
TCHAR
#ifdef UNICODE
typedef wchar_t ? - 註意定義宏的位置,#ifdef
XXX 具有向上朔源的屬性,如果代碼中有多個ifdef
XXX 就應該讓它統一的找到定義,或者找不到定義,不能自相矛盾。
示範代碼 定義宏的位置(#define UNICODE)要在windows.h文件的前面定義,因為windows.h頭文件包含有WINNT.H文件,WINNT.H裏面有“#ifdef UNICODE”的判斷檢測。
#define UNICODE
#include "stdafx.h"
#include "stdio.h"
#include <tchar.h>
#include <windows.h>
void T_char()
{
TCHAR *pszText = _TEXT("Hello");
#ifdef UNICODE
wprintf(L"%s\n",pszText);
#else
printf("單:%s\n",pszText);
#endif
}
int main()
{
T_char();
return 0;
} - 示例:
UNICODE編碼中wprintf函數的支持有限,不完善,需要更換
// WinChar.cpp : Defines the entry point for the console application.
//
#define UNICODE
#include "stdafx.h"
#include "stdio.h"
#include <tchar.h>
#include <windows.h>
void PrintUnicode()
{
for (WORD nHigh = 0; nHigh <256; nHigh++)
{
for (WORD nLow = 0; nLow<256; nLow++)
{
wchar_t wChar = nHigh * 256 +nLow;
wprintf(L"%s",&wChar);
}
printf("\n");
}
}
int main()
{
PrintUnicode();
return 0;
} - UNICODE打印輸出要使用
WriteConsole這個API來實施。
BOOL WriteConsole(
?IN HANDLE hConsoleOutput, //標準輸出句柄
?IN CONST VOID *lpBuffer, //輸出內容的Buffer緩沖
?IN DWORD nNumberOfCharsToWrite, //準備輸出內容長度
?OUT LPDWORD lpNumberOfCharsWritten, //返回實際輸出內容長度
?IN LPVOID lpReserved //備用
? ); - 只有三個特殊的指向設備的句柄:1
鍵盤 2 顯示器
3 錯誤設備 (其它句柄均指向內存)
HANDLE WINAPI GetStdHandle(
_In_ DWORD nStdHandle //input,output, or error device
);//返回值 獲取相應的標準句柄
Win32API UNICODE編碼&寬字節