tchar.h及TCHAR數據類型介紹

並不是所有的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符號。


  1. / 定義宏UNICODE和_UNICODE, 一旦定義了該宏, C語言編譯器將在UNICODE環境下工作    
  2. // 注意, 一般情況下需要定義UNICODE宏和_UNICODE宏, 因爲不同版本的C編譯器要求不同    
  3.     
  4. // 在正式工作時, 並不需要定義這兩個宏, 只需要在"項目屬性->配置屬性->字符集"中選擇    
  5. // UNICODE字符集或是多字節字符集即可, 開發環境會自動定義相應的宏    
  6. #if !defined(UNICODE)    
  7. #define UNICODE    
  8. #endif    
  9.     
  10. #if !defined(_UNICODE)    
  11. #define _UNICODE    
  12. #endif    
  13.     
  14. // 在所有頭文件之前包含tchar.h頭文件    
  15. // 這是程序可以應用各類替代宏的基礎    
  16. #include <tchar.h>    
  17. #include <locale.h>    
  18. #include <stdio.h>    
  19. #include <stdlib.h>    
  20. #include <windows.h>    
  21.     
  22. /**  
  23.  * 顯示一個字符, ASCII版本  
  24.  * 參數:c, 要顯示的字符變量  
  25.  */    
  26. void ShowCharacterA(char c)    
  27. {    
  28.     // 在ASCII版本中, 選用printf函數來顯示字符串    
  29.     printf("(A)字符 %c 佔據空間 %d", c, sizeof(c));    
  30. }    
  31.     
  32. /**  
  33.  * 顯示一個字符, UNICODE版本  
  34.  * 參數:c, 要顯示的字符變量  
  35.  */    
  36. void ShowCharacterW(wchar_t wc)    
  37. {    
  38.     // 在UNICODE版本中, 選用wprintf函數來顯示UNICODE字符串    
  39.     wprintf(L"(W)字符 %c 佔據空間 %d", wc, sizeof(wc));    
  40. }    
  41.     
  42. /**  
  43.  * 顯示一個字符串, ASCII版本  
  44.  * 參數:lpcsz, 要顯示的字符變量  
  45.  */    
  46. void ShowStringA(const char* lpcsz)    
  47. {    
  48.     // 在ASCII版本中, 選用printf函數來顯示ASCII字符串,     
  49.     // 選用strlen函數來測量字符串長度    
  50.     printf("/n(A)字符串 %s 長度爲%d", lpcsz, strlen(lpcsz));    
  51. }    
  52.     
  53. /**  
  54.  * 顯示一個字符串, UNICODE版本  
  55.  * 參數:lpcwsz, 要顯示的字符變量  
  56.  */    
  57. void ShowStringW(const wchar_t* lpcwsz)    
  58. {    
  59.     // 在UNICODE版本中, 選用wprintf函數來顯示UNICODE字符串,     
  60.     // 選用wcslen函數來測量字符串長度    
  61.     wprintf(L"/n(W)字符串 %s 長度爲%d", lpcwsz, wcslen(lpcwsz));    
  62. }    
  63.     
  64.     
  65. ////////////////////////////////////////////////////    
  66.     
  67. // 下面這一組編譯器指令, 根據是否定義UNICODE(或_UNICODE)宏, 映射不同的函數    
  68. // 可以刪除#if和#endif之間的代碼, 查看運行結果的變化, 思考產生這種變化的原因    
  69. #if defined(UNICODE) | defined(_UNICODE)    
  70.     
  71. // 定義ShowCharacter宏映射到ShowCharacterW函數    
  72. #define ShowCharacter ShowCharacterW    
  73.     
  74. // 定義ShowString宏映射到ShowStringW函數    
  75. #define ShowString ShowStringW    
  76.     
  77. #else    
  78.     
  79. // 定義ShowCharacter宏映射到ShowCharacterA函數    
  80. #define ShowCharacter ShowCharacterA    
  81.     
  82. // 定義ShowString宏映射到ShowStringA函數    
  83. #define ShowString ShowStringA    
  84.     
  85. #endif    
  86.     
  87. ////////////////////////////////////////////////////    
  88.     
  89. // 定義緩衝區長度爲512個字符    
  90. #define BUF_LEN 512    
  91.     
  92. int _tmain(int argc, TCHAR* argv[])    
  93. {    
  94.     // 定義變量, 保存字符    
  95.     TCHAR c = _T('A');    
  96.     
  97.     // 定義字符數組, 保存字符串    
  98.     TCHAR szStr[] = _T("ABC大家好");    
  99.     
  100.     // 定義指向字符串的指針    
  101.     TCHAR* lpszStr = _T("Hello你好");    
  102.     
  103.     // 定義指向字符串的常量指針    
  104.     const TCHAR* lpcszStr = _T("GoodBye再見");    
  105.     
  106.     int bSame;    
  107.     
  108.     // 定義BUF_LEN長度的字符數組作爲緩衝區    
  109.     TCHAR szBuffer[BUF_LEN] = _T("");           
  110.     
  111.     // 定義ASCII字符集緩衝區    
  112.     char szBufferA[BUF_LEN] = "";    
  113.     
  114.     // 定義UNICODE字符集緩衝區    
  115.     wchar_t szBufferW[BUF_LEN] = L"";    
  116.     
  117.     // 定義錯誤代碼22    
  118.     const int nError = 22;    
  119.     
  120.     // 設置語言環境爲中文    
  121.     _tsetlocale(LC_ALL, _T("zhi"));    
  122.     
  123.     // 調用ShowCharacter宏    
  124.     ShowCharacter(c);    
  125.     
  126.     // 調用ShowCharacter宏    
  127.     ShowString(szStr);    
  128.     ShowString(lpszStr);    
  129.     ShowString(lpcszStr);    
  130.     
  131.     // _tcsicmp是tchar.h中定義的宏,     
  132.     // 在不同的字符集環境下映射爲stricmp或wcsicmp函數    
  133.     bSame = _tcsicmp(lpszStr, lpcszStr);    
  134.     
  135.     if (bSame == 0)     
  136.     {    
  137.         // _tprintf是tchar.h中定義的宏, 在不同字符集環境下映射爲printf或wprintf函數    
  138.         _tprintf(_T("/n字符串 %s 與 %s 相同"), lpszStr, lpcszStr);    
  139.     }     
  140.     else     
  141.         _tprintf(_T("/n字符串 %s 與 %s 不同"), lpszStr, lpcszStr);    
  142.     
  143.     // _tcscpy_s是tchar.h中定義的宏,    
  144.     // 在不同字符集環境下映射爲strcpy_s或wcscpy_s函數(_s表示安全版本函數)    
  145.     _tcscpy_s(szBuffer, BUF_LEN, lpszStr);    
  146.     
  147.     // _tcscat_s是tchar.h中定義的宏,     
  148.     // 在不同字符集環境下映射爲strcat_s或wcscat_s函數(_s表示安全版本函數)    
  149.     _tcscat_s(szBuffer, BUF_LEN, lpcszStr);    
  150.     
  151.     // _tcslen是tchar.h中定義的宏,     
  152.     // 在不同字符集環境下映射爲strlen或wcslen函數    
  153.     _tprintf(_T("/n字符串 %s 長度爲 %d"), szBuffer, _tcslen(szBuffer));    
  154.     
  155.     // 接下來, 我們看一下FormatMessage函數在不同環境下的應用    
  156.     
  157.     // ASCII環境下應用, 第5個參數使用char類型數組作爲緩衝    
  158.     FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);    
  159.     printf("/n錯誤信息:%s", szBufferA);    
  160.     
  161.     // UNICODE環境下應用, 第5個參數使用wchar_t類型數組作爲緩衝    
  162.     FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);    
  163.     wprintf(L"錯誤信息:%s", szBufferW);    
  164.     
  165.     // 自適應環境, 第5個參數使用TCHAR類型數組作爲緩衝    
  166.     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);    
  167.     _tprintf(_T("錯誤信息:%s"), szBuffer);    
  168.     
  169.     _tprintf(_T("/n"));    
  170.     system("pause");    
  171.     return 0;    
  172. }    

    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

發佈了56 篇原創文章 · 獲贊 95 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章