被搞得暈頭轉向的LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR

首先明確一點,這些都是C++定義的宏,爲了讓程序開發更方便快捷,下面是MSDN中的一個表格:

宏定義對照表
類型 MBCS Unicode
WCHAR wchar_t wchar_t
LPSTR char* char*
LPCSTR const char* const char*
LPWSTR wchar_t* wchar_t*
LPCWSTR const wchar_t* const wchar_t*
TCHAR char wchar_t
LPTSTR TCHAR*(或char*) TCHAR* (或wchar_t*)
LPCTSTR const TCHAR* const TCHAR*

表中可以發現其實這麼多宏,也就是兩種基本的數據結構數據結構:char和wchar_t:

char是8位字符類型,最多隻能包含256種字符,許多外文字符集所含的字符數目超過256個,char型無法表示。

wchar_t數據類型一般爲16位或32位,但不同的C或C++庫有不同的規定,如GNU Libc規定wchar_t爲32位,總之,wchar_t所能表示的字符數遠超char型。

參考博客:

http://m.blog.csdn.net/article/details?id=739717

可以用下列幾種方法之一將它轉換成char類型串:

1、調用 WideCharToMultiByte() API;
2、調用CRT 函數wcstombs(),注意,在轉換英文的時候沒有問題,在轉換中文時,wcstombs()函數會返回-1;
3、使用CString 構造器或賦值操作(僅用於MFC );
4、使用ATL 串轉換宏W2A()。

1.WideCharToMultiByte()
    你可以用WideCharToMultiByte()將一個Unicode串轉換成一個ANSI串。此函數的原型如下:
    int WideCharToMultiByte ( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar );
以下是參數解釋:
CodePage
    Unicode字符轉換成的代碼頁。你可以傳遞CP_ACP來使用當前的ANSI代碼頁。代碼頁是256個字符集。字符0――127與ANSI編碼一樣。字符128――255與ANSI字符不同,它可以包含圖形字符或者讀音符號。每一種語言或地區都有其自己的代碼頁,所以使用正確的代碼頁對於正確地顯示重音字符很重要。
dwFlags
    dwFlags 確定Windows如何處理“複合” Unicode字符,它是一種後面帶讀音符號的字符。如è就是一個複合字符。如果這些字符在CodePage參數指定的代碼頁中,不會出什麼事。否則,Windows必須對之進行轉換。
    傳遞WC_COMPOSITECHECK使得這個API檢查非映射複合字符。
    傳遞WC_SEPCHARS使得Windows將字符分爲兩段,即字符加讀音,如e`。
    傳遞WC_DISCARDNS使得Windows丟棄讀音符號。
    傳遞WC_DEFAULTCHAR使得Windows用lpDefaultChar參數中說明的缺省字符替代複合字符。
    缺省行爲是WC_SEPCHARS。
lpWideCharStr
    要轉換的Unicode串。
cchWideChar
    lpWideCharStr在Unicode 字符中的長度。通常傳遞-1,表示這個串是以0x00結尾。
lpMultiByteStr
    接受轉換的串的字符緩衝
cbMultiByte
    lpMultiByteStr的字節大小。
lpDefaultChar
    可選――當dwFlags包含WC_COMPOSITECHECK | WC_DEFAULTCHAR並且某個Unicode字符不能被映射到同等的ANSI串時所傳遞的一個單字符ANSI串,包含被插入的“缺省”字符。可以傳遞NULL,讓API使用系統缺省字符(一種寫法是一個問號)。
lpUsedDefaultChar
    可選――指向BOOL類型的一個指針,設置它來表示是否缺省字符曾被插入ANSI串。可以傳遞NULL來忽略這個參數。

2,wcstombs() 
    這個CRT函數wcstombs()是個簡化版,但它終結了WideCharToMultiByte()的調用,所以最終結果是一樣的。其原型如下: 
size_t wcstombs (  char*   mbstr, const wchar_t* wcstr, size_t    count );

以下是參數解釋: 
mbstr 
接受結果ANSI串的字符(char)緩衝。 
wcstr 
要轉換的Unicode串。 
count 
mbstr參數所指的緩衝大小。

     wcstombs()在它對WideCharToMultiByte()的調用中使用WC_COMPOSITECHECK | WC_SEPCHARS標誌。用wcstombs()轉換前面例子中的Unicode串,結果一樣:

     wcstombs ( szANSIString, wszSomeString, sizeof(szANSIString) );

3.CString 
     MFC中的CString包含有構造函數和接受Unicode串的賦值操作,所以你可以用CString來實現轉換。例如:

// 假設有一個Unicode串wszSomeString...
CString str1 ( wszSomeString ); // 用構造器轉換 
CString str2;
str2 = wszSomeString; // 用賦值操作轉換

4.ATL宏 
       ATL有一組很方便的宏用於串的轉換。W2A()用於將Unicode串轉換爲ANSI串(記憶方法是“wide to ANSI”――寬字符到ANSI)。

//使用ATL的W2A和A2W宏必須使用USES_CONVERSION
USES_CONVERSION;
  
//Unicode字符串
wchar_t* wszText=L"1.Unicode字符轉換爲ANSI;";
printf("%s\n",W2A(wszText));

//用wprintf輸出非英文字符,需要設置當前的地域信息
setlocale(LC_ALL,"chs");
  
//ANSI字符串(ANSI:American National Standards Institute)
//中文內碼MBCS:Multi-Byte character sets,英文內碼SBCS:Single-Byte character sets)
char* szText="2.ANSI字符轉換成Unicode.";
wprintf(L"%s\n",A2W(szText));



如果要從char數據類型轉換到wchar_t也有上述四種方法中三種方法的對應函數:

1、調用MultiByteToWideChar() API;

2、調用CRT 函數mbstowcs();
3、使用CString 構造器或賦值操作(僅用於MFC );
4、使用ATL 串轉換宏A2W()。 



最後附上兩個String和WString相互轉換的的函數:

//wstring轉換成string
std::string WChar2Ansi(LPCWSTR pwszSrc)
{
	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);

	if (nLen <= 0) return std::string("");

	char* pszDst = new char[nLen];
	if (NULL == pszDst) return std::string("");

	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
	pszDst[nLen - 1] = 0;

	std::string strTemp(pszDst);
	delete[] pszDst;

	return strTemp;
}

//string轉換車wstring
std::wstring  StringToWString(const std::string& s)
{
	std::wstring wszStr;

	int nLength = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, NULL);
	wszStr.resize(nLength);
	LPWSTR lpwszStr = new wchar_t[nLength];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, lpwszStr, nLength);
	wszStr = lpwszStr;
	delete[] lpwszStr;
	return wszStr;
}


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