1. 程式人生 > >C++多位元組與寬位元組 轉換

C++多位元組與寬位元組 轉換

  wsprintf要求的第一個引數是LPTSTR,假設環境是UNICODE的,那麼LPTSTR相當於就是wchar_t* 就是寬字元指標,在非Unicode環境下就是char*。

  有關格式化字串的函式還有如下,詳細用法各位可以檢視MSDN,和上面所介紹的都差不多:

    sprintf 單位元組版本的C/C++庫函式

    swprintf 寬位元組版本的C/C++庫函式

  而我們上面的wsprintf和上面兩個函式看起來很相似,大家不要搞混淆了啊,wsprintf最前面的w不是代表Wide,寬位元組的意思了,而是Windows的W,代表是windows的API函數了,其實它是一個巨集這在上面已經說過了,真正的API函式其實是wsprintfA和wsprintfW這兩個,在不嚴格的情況下通常我們也說wsprintf是函式。

char,TCHAR,WCHAR區別

#ifdef UNICODE
typedef wchar_t TCHAR;

#else
typedef unsigned char TCHAR;

#endif
typedef unsigned char CHAR;
typedef unsigned wchar_t WCHAR;

由此可以看出,CHAR實施上就是unsigned char,WCHAR為寬字元,而TCHAR根據是否支援unicode而不同。

在程式使用sizeof(TCAHR),當預設設定時,這個值是1;當定義UNICODE巨集時,這個值是2。

C++標準庫函式提供了字元和字串的操作函式,並提供了其UNICODE版本,如:

  1. char *strcpy(char *strDestination, constchar *strSource);
  2. wchar_t *wcscpy(wchar_t *strDestination, constwchar_t *strSource);

wcscpy()即為strcpy()的寬字元版本,與_T類似的,Visual C++提供了類似的同名函式:

  1. #ifdef UNICODE
  2. #define _tcscpy wcscpy
  3. #else
  4. #define _tcscpy strcpy
  5. #endif

_tcscpy
在編譯時會根據條件被替換,
如果是 非UNICODE 工程,它就被替換為 strcpy
UNICODE 工程被替換為 wcscpy

下是使用strcpy_s與strcpy的安全性比較

char szBuf[2] = {0};

strcpy_s(szBuf, 2, "12131"); //新的CRT函式
strcpy(szBuf, "12131"); //老的CRT函式

上述程式碼,明顯有緩衝區溢位的問題。 使用strcpy_s函式則會丟擲一個異常。而使用strcpy函式的結果則未定,因為它錯誤地改變了程式中其他部分的記憶體的資料,可能不會丟擲異常但導致程式資料錯誤,也可能由於非法記憶體訪問丟擲異常。

使用新的增強安全的CRT函式有什麼好處呢?簡單地說,新的函式加強了對引數合法性的檢查以及緩衝區邊界的檢查,如果發現錯誤,會返回errno或丟擲異常。老版本的這些CRT函式則沒有那麼嚴格的檢查與校驗,如果錯誤地傳輸了引數或者緩衝區溢位,那麼錯誤並不能被立刻發現,對於定位程式錯誤也帶來更大困難。