Windows數據類型,Windows程序字符集知識總結

此文章是根據如下文章和自己的思考總結歸納整理出來的:

https://www.cnblogs.com/zhangdongsheng/archive/2011/08/16/2141513.html

http://www.voidcn.com/article/p-chwlarat-hs.html

字符集

首先要知道通常Windows平臺下的程序設計可以支持ANSI和UNICODE兩種編碼方法的字符串(Windows95 、98上不支持UNICODE標準)。

  1. ANSI:即多字節字符集(Multi-Byte Character System),它是編碼的一種類型,而不是某個特定編碼的名稱。它是不定長表示世界文字的編碼方式。ANSI編碼表示英文字符時用一個字節(同ASCII編碼),表示其他文字時就需要使用多字節(表示中文時用兩個字節)。
  2. Unicode:用兩個字節表示一個字符的編碼方式。比如字符'A'在ASCII下面用一個字節表示,而在Unicode下面用兩個字節表示,其中高字節用“0”填充。Unicode是定長表示世界文字的編碼方式,據統計,用兩個字節可以編碼現存的所有文字而沒有二義。

在visual studio中,可以再這裏設置字符集

WINDOWS數據類型

VC++中的char,wchar_t,TCHAR

大家一起做一個項目,經常發現有的人愛用strcpy等標準ANSI函數,有的人愛用_tXXXX函數,這個問題曾經搞的很混亂。爲了統一,有必要把來龍去脈搞清楚。

爲了搞清這些函數,就必須理請幾種字符類型的寫法。char就不用說了,先說一些wchar_t。wchar_t是Unicode字符的數據類型,它實際定義在<string.h>裏:

typedef unsigned short wchar_t;


不能使用類似 strcpy這樣的ANSI C字符串函數來處理wchar_t字符串,必須使用wcs前綴的函數,例如wcscpy。爲了讓編譯器識別Unicode字符串,必須以在前面加一個 “L”,例如:

wchar_t *szTest=L"This is a Unicode string.";

下面在看看TCHAR。如果你希望同時爲ANSI和Unicode編譯的源代碼,那就要include TChar.h。TCHAR是定義在其中的一個宏,它視你是否定義了_UNICODE宏而定義成char或者wchar_t。如果你使用了TCHAR,那麼就不應該使用ANSI的strXXX函數或者Unicode的wcsXXX函數了,而必須使用TChar.h中定義的_tcsXXX函數。另外,爲了解決剛纔提到帶“L”的問題,TChar.h中定義了一個宏:“_TEXT”。

以strcpy函數爲例子,總結一下:
.如果你想使用ANSI字符串,那麼請使用這一套寫法:

char szString[100];
strcpy(szString,"test");


.如果你想使用Unicode字符串,那麼請使用這一套:

wchar_t szString[100];
wcscpyszString,L"test");


.如果你想通過定義_UNICODE宏,而編譯ANSI或者Unicode字符串代碼:

TCHAR szString[100];
_tcscpy(szString,_TEXT("test"));

字符串及處理:使用TCHAR系列方案

使用TCHAR系列方案編寫程序
  TCHAR是一種字符串類型,它讓你在以MBCS和UNNICODE來build程序時可以使用同樣的代碼,不需要使用繁瑣的宏定義來包含你的代碼。
      TCHAR的引入,主要是在Tchar.h文件中,該文件包含這方面的重要的定義信息。
      對於包含了對str函數或wcs函數進行顯式調用的代碼來說,無法非常容易地同時爲ANSI和Unicode對這些代碼進行編譯。本章前面說過,可以創建同時爲ANSI和Unicode進行編譯的單個源代碼文件。若要建立雙重功能,必須包含TChar.h文件,而不是包含String.h文件。
      TChar.h文件的唯一作用是幫助創建ANSI/Unicode通用源代碼文件。它包含你應該用在源代碼中的一組宏,而不應該直接調用str函數或者 wcs函數。如果在編譯源代碼文件時定義了_UNICODE,這些宏就會引用wcs這組函數。如果沒有定義_UNICODE,那麼這些宏將引用str這組宏。
      TCHAR的定義如下:

      #ifdef UNICODE
      typedef wchar_t TCHAR;
      #else
      typedef char TCHAR;
      #endif


      所以用MBCS來build時,TCHAR是char,使用UNICODE時,TCHAR是wchar_t。
      還有一個宏來處理定義Unicode字符串常量時所需的L前綴。

      #ifdef UNICODE
      #define _T(x) L##x
      #define _TEXT(x) L##x
      #define __T(x) L##x
      #else
      #define _T(x) x
      #define _TEXT(x) x
      #define __T(x) x
      #endif


     ## 是一個預處理操作符,它可以把兩個參數連在一起。如果你的代碼中需要字符串常量,在它前面加上_T宏。如果你使用Unicode來build,它會在字符串常量前加上L前綴。
      TCHAR szNewText[] = _T("we love Bob!");
    _UNICODE宏用於C運行期頭文件,而UNICODE宏則用於Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。
  像是用宏來隱藏SetWindowTextA/W的細節一樣,還有很多可以供你使用的宏來實現str***()和_mbs***()等字符串函數。例如,你可以使用_tcsrchr宏來替換strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根據你預定義的宏是_MBCS還是 UNICODE來擴展成正確的函數,就象SetWindowText所作的一樣。
   不僅str***()函數有TCHAR宏。其他的函數如, _stprintf(代替sprinft()和swprintf()),_tfopen(代替fopen()和_wfopen())。 MSDN中"Generic-Text Routine Mappings."標題下有完整的宏列表。

下面來解釋下幾個指針類型的具體意思:

LPSTR: 32-bit指針指向一個字符串,每個字符佔1字節。相當於char *

LPCSTR:: 32-bit指針指向一個常量字符串,每個字符佔1字節。相當於const char *

LPTSTR: 32-bit指針每字符可能佔1字節或2字節,取決於Unicode宏是否定義。相當於TCHAR *(或_TCHAR *)

LPCTSTR: 32-bit指針指向一個常量字符串,每字符可能佔1字節或2字節,取決於Unicode宏是否定義。相當於const THCAR *(或const _TCHAR *)

LPWSTR: 32-bit指針指向一個Unicode字符串的指針,每個字符佔2字節。相當於wchar_t *

LPCWSTR: 32-bit指針指向一個Unicode字符串常量的指針,每個字符佔2字節。相當於const wchar_t *


LPBYTE: 32-bit指針指向一個字節的指針,相當於unsigned char * 

 

(L表示long, P表示pointer,C表示constant,,T表示指針指向的字符佔的字節數取決於Unicode是否定義——即_T宏,W表示wide,STR就是string的意思)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章