寬字元(Wide character) 是計算機抽象術語(沒有規定具體實現細節),表示比1字節還寬的資料類型。不同於Unicode

Unicode

ISO/IEC 10646:2003 Unicode 4.0 指出:

"The width of wchar_t is compiler-specific and can be as small as 8 bits. Consequently, programs that need to be portable across any C or C++ compiler should not use wchar_t for storing Unicode text. The wchar_t type is intended for storing compiler-defined wide characters, which may be Unicode characters in some compilers." 翻譯:「wchar_t的寬度屬於編譯器的特性,且可以小到8位元。所以程式若需要跨過所有C和C++ 編譯器的可攜性,就不應使用wchar_t儲存Unicode文字。wchar_t類型是為儲存編譯器定義的寬字元,在部分編譯器中,其可以是Unicode字元。」
"ANSI/ISO C leaves the semantics of the wide character set to the specific implementation but requires that the characters from the portable C execution set correspond to their wide character equivalents by zero extension."

操作系統

對於Windows APIVisual Studio編譯器,wchar_t是16位元寬。由於不能在單個wchar_t字元中,支援系統所有可表示的字元(即UTF-16小尾字元),因而破壞了ANSI/ISO C標準。

在類Unix系統中,wchar_t是32位元寬。單個wchar_t字元可表示任意UTF-32大尾字元。

程序設計語言

C/C++

wchar_t在ANSI/ISO C中是一個資料類型。某些其它的程式語言也用它來表示寬字元。在ANSI C程式庫表頭檔中,<wchar.h>和<wctype.h>處理寬字元。

最初,C90語言標準定義了類型wchar_t

"an integral type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales" (ISO 9899:1990 §4.1.5)

C語言與C++語言於2011年發布的各自語言標準中引入了固定大小的字符類型char16_tchar32_twchar_t仍保持由編譯器實現定義其細節。

Python

Python語言使用wchar_t作為字符類型Py_UNICODE的基礎。它依賴於該系統是否 wchar_t「兼容於被選擇的Python Unicode編譯版本」。[1]

寬窄轉換

任何非寬字符的字符集,無論是單字節字符集(SBCS),還是(可變長)多字節字符集(MBCS),都稱作窄字符集(narrow character set)。

寬字符集的一個用途,是作為任意兩個窄字符集相互轉換的中間表示。

寬字符集與窄字符集的轉換,有多種方法。

使用Windows API

例如:

// we want to convert an MBCS string in lpszA  
int nLen = MultiByteToWideChar(CP_ACP,
    0,
    lpszA, -1,
    NULL,
    NULL);

LPWSTR lpszW = new WCHAR[nLen];  
MultiByteToWideChar(CP_ACP,
    0,   
    lpszA, -1,
    lpszW,
    nLen);

// use it to call OLE here  
pI->SomeFunctionThatNeedsUnicode(lpszW);

// free the string  
delete[] lpszW;

使用ATL 3.0的字符串轉換宏

在Microsoft的atlconv.h中,定義了四個宏:

  • A2CW : (LPCSTR) -> (LPCWSTR)
  • A2W : (LPCSTR) -> (LPWSTR)
  • W2CA : (LPCWSTR) -> (LPCSTR)
  • W2A : (LPCWSTR) -> (LPSTR)

使用前需要先用宏定義中間輔助變量:

USES_CONVERSION;

上述四個宏的轉化過程為:對輸入字符串,按照2比1計算寬窄字符串長度關係;然後在運行棧上分配出空間,調用ATLW2AHELPER或ATLA2WHELPER幫助函數完成轉換。優點是代碼退出當前程序塊,棧上的空間被自動回收。缺點是寬窄字符2比1的大小關係,僅適用於單字節字符集。[2]

另外,需要注意不要在大量循環結構中使用轉換宏,這會導致快速耗用棧空間。可以把轉換宏寫到一個小函數中。

使用ATL 7.0的字符串轉換類與宏

字符串轉換類(模板)的格式為:

 C SourceType 2[ C]DestinationType[ EX]

其中SourceType與DestinationType可以是A、W、T、OLE(等價於W)。中間可選的C表示結果為const。EX表示緩衝區存放的字符數由模板參數指定。

缺省的靜態緩衝區大小為128個字符。可以指定帶EX後綴的模板的參數,以節約空間。可以使用第二個參數指定窄字符的locale。如果運行棧的剩餘空間不夠用,自動在堆上分配空間,並在超出了該變量的作用域是自動釋放堆上的空間。不需要使用USES_CONVERSION宏。注意作為局部對象,如果是無名的臨時實例,表達式結束時該變量將自動析構,事後再引用該實例所含的結果字符串將無效。[3]

使用_bstr_t類

適用於Microsoft開發平台。示例:

#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
 
std::string ws2s(const std::wstring& ws)
{
    _bstr_t t = ws.c_str();
    char* pchar = (char*)t;
    std::string result = pchar;
    return result;
}

C語言標準庫函數mbstowcs()和wcstombs()

定義於stdlib.h。需要預先分配目標緩衝區。

參考文獻

  1. ^ https://docs.python.org/c-api/unicode.html頁面存檔備份,存於網際網路檔案館) accessed 2009 12 19
  2. ^ MSDN TN059: Using MFC MBCS/Unicode Conversion Macros. [2018-01-12]. (原始內容存檔於2018-01-12). 
  3. ^ MSDN: ATL and MFC String Conversion Macros. [2018-01-12]. (原始內容存檔於2018-01-12).