並不是所有的Windows操作系統都支持UNICODE編碼的API(例如早期的Windows98), 這就造成了兩種結果:某些版本的Windows應該應用wchar_t來保存字符, 某些平臺的Windows應該使用char類型來保存字符, 顯然這兩種類型的變量是無法混用的。
爲了解決該問題, Windows從一開始設計Windows時, 就提供了一整套方案, 對於支持ASCII字符集的API函數, 函數使用字母A作爲後綴;對於支持UNICODE字符集的API函數, 則使用字母W作爲後綴。
例如:FormatMessage函數就提供了FormatMessageA和FormatMessageW兩個版本。
文檔記載及我們使用的API函數, 實際是定義在Windows.h文件中的一組“宏”, 這組宏在UNICODE環境下將調用函數映射爲後綴爲W的函數;在ASCII環境下將調用函數映射爲後綴爲A的函數。
tchar.h頭文件提供了一個數據類型TCHAR, 這個類型在UNICODE環境下將映射爲wchar_t類型;在ASCII環境下映射爲char類型。另外, tchar.h還提供了一組C語言字符串操作符的替代宏, 以_t開頭, 例如_tcslen函數, 在UNICODE環境下被映射成爲wcslen函數, 在ASCII環境下被映射成爲strlen函數。
最後, tchar.h提供了_T宏, 該宏具有一個字符串類型參數, 在UNICODE環境下, 該宏會爲字符串前面加上L符號。
- / 定義宏UNICODE和_UNICODE, 一旦定義了該宏, C語言編譯器將在UNICODE環境下工作
- // 注意, 一般情況下需要定義UNICODE宏和_UNICODE宏, 因爲不同版本的C編譯器要求不同
- // 在正式工作時, 並不需要定義這兩個宏, 只需要在"項目屬性->配置屬性->字符集"中選擇
- // UNICODE字符集或是多字節字符集即可, 開發環境會自動定義相應的宏
- #if !defined(UNICODE)
- #define UNICODE
- #endif
- #if !defined(_UNICODE)
- #define _UNICODE
- #endif
- // 在所有頭文件之前包含tchar.h頭文件
- // 這是程序可以應用各類替代宏的基礎
- #include <tchar.h>
- #include <locale.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- /**
- * 顯示一個字符, ASCII版本
- * 參數:c, 要顯示的字符變量
- */
- void ShowCharacterA(char c)
- {
- // 在ASCII版本中, 選用printf函數來顯示字符串
- printf("(A)字符 %c 佔據空間 %d", c, sizeof(c));
- }
- /**
- * 顯示一個字符, UNICODE版本
- * 參數:c, 要顯示的字符變量
- */
- void ShowCharacterW(wchar_t wc)
- {
- // 在UNICODE版本中, 選用wprintf函數來顯示UNICODE字符串
- wprintf(L"(W)字符 %c 佔據空間 %d", wc, sizeof(wc));
- }
- /**
- * 顯示一個字符串, ASCII版本
- * 參數:lpcsz, 要顯示的字符變量
- */
- void ShowStringA(const char* lpcsz)
- {
- // 在ASCII版本中, 選用printf函數來顯示ASCII字符串,
- // 選用strlen函數來測量字符串長度
- printf("/n(A)字符串 %s 長度爲%d", lpcsz, strlen(lpcsz));
- }
- /**
- * 顯示一個字符串, UNICODE版本
- * 參數:lpcwsz, 要顯示的字符變量
- */
- void ShowStringW(const wchar_t* lpcwsz)
- {
- // 在UNICODE版本中, 選用wprintf函數來顯示UNICODE字符串,
- // 選用wcslen函數來測量字符串長度
- wprintf(L"/n(W)字符串 %s 長度爲%d", lpcwsz, wcslen(lpcwsz));
- }
- ////////////////////////////////////////////////////
- // 下面這一組編譯器指令, 根據是否定義UNICODE(或_UNICODE)宏, 映射不同的函數
- // 可以刪除#if和#endif之間的代碼, 查看運行結果的變化, 思考產生這種變化的原因
- #if defined(UNICODE) | defined(_UNICODE)
- // 定義ShowCharacter宏映射到ShowCharacterW函數
- #define ShowCharacter ShowCharacterW
- // 定義ShowString宏映射到ShowStringW函數
- #define ShowString ShowStringW
- #else
- // 定義ShowCharacter宏映射到ShowCharacterA函數
- #define ShowCharacter ShowCharacterA
- // 定義ShowString宏映射到ShowStringA函數
- #define ShowString ShowStringA
- #endif
- ////////////////////////////////////////////////////
- // 定義緩衝區長度爲512個字符
- #define BUF_LEN 512
- int _tmain(int argc, TCHAR* argv[])
- {
- // 定義變量, 保存字符
- TCHAR c = _T('A');
- // 定義字符數組, 保存字符串
- TCHAR szStr[] = _T("ABC大家好");
- // 定義指向字符串的指針
- TCHAR* lpszStr = _T("Hello你好");
- // 定義指向字符串的常量指針
- const TCHAR* lpcszStr = _T("GoodBye再見");
- int bSame;
- // 定義BUF_LEN長度的字符數組作爲緩衝區
- TCHAR szBuffer[BUF_LEN] = _T("");
- // 定義ASCII字符集緩衝區
- char szBufferA[BUF_LEN] = "";
- // 定義UNICODE字符集緩衝區
- wchar_t szBufferW[BUF_LEN] = L"";
- // 定義錯誤代碼22
- const int nError = 22;
- // 設置語言環境爲中文
- _tsetlocale(LC_ALL, _T("zhi"));
- // 調用ShowCharacter宏
- ShowCharacter(c);
- // 調用ShowCharacter宏
- ShowString(szStr);
- ShowString(lpszStr);
- ShowString(lpcszStr);
- // _tcsicmp是tchar.h中定義的宏,
- // 在不同的字符集環境下映射爲stricmp或wcsicmp函數
- bSame = _tcsicmp(lpszStr, lpcszStr);
- if (bSame == 0)
- {
- // _tprintf是tchar.h中定義的宏, 在不同字符集環境下映射爲printf或wprintf函數
- _tprintf(_T("/n字符串 %s 與 %s 相同"), lpszStr, lpcszStr);
- }
- else
- _tprintf(_T("/n字符串 %s 與 %s 不同"), lpszStr, lpcszStr);
- // _tcscpy_s是tchar.h中定義的宏,
- // 在不同字符集環境下映射爲strcpy_s或wcscpy_s函數(_s表示安全版本函數)
- _tcscpy_s(szBuffer, BUF_LEN, lpszStr);
- // _tcscat_s是tchar.h中定義的宏,
- // 在不同字符集環境下映射爲strcat_s或wcscat_s函數(_s表示安全版本函數)
- _tcscat_s(szBuffer, BUF_LEN, lpcszStr);
- // _tcslen是tchar.h中定義的宏,
- // 在不同字符集環境下映射爲strlen或wcslen函數
- _tprintf(_T("/n字符串 %s 長度爲 %d"), szBuffer, _tcslen(szBuffer));
- // 接下來, 我們看一下FormatMessage函數在不同環境下的應用
- // ASCII環境下應用, 第5個參數使用char類型數組作爲緩衝
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);
- printf("/n錯誤信息:%s", szBufferA);
- // UNICODE環境下應用, 第5個參數使用wchar_t類型數組作爲緩衝
- FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);
- wprintf(L"錯誤信息:%s", szBufferW);
- // 自適應環境, 第5個參數使用TCHAR類型數組作爲緩衝
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);
- _tprintf(_T("錯誤信息:%s"), szBuffer);
- _tprintf(_T("/n"));
- system("pause");
- return 0;
- }
wchar_t是C/C++的字符類型,是一種擴展的存儲方式,wchar_t類型主要用在國際化程序的實現中,但它不等同於uni編碼。uni編碼的字符一般以wchar_t類型存儲。
char是8位字符類型,最多隻能包含256種字符,許多外文字符集所含的字符數目超過256個,char型無法表示。
wchar_t數據類型一般爲16位或32位,但不同的C或C++庫有不同的規定,如GNU Libc規定wchar_t爲32位,總之,wchar_t所能表示的字符數遠超char型。
標準C++中的wprintf()函數以及iostream類庫中的類和對象能提供wchar_t寬字符類型的相關操作。
轉自:http://blog.csdn.net/gvfdbdf/article/details/48597407