1. 程式人生 > >char*, wchat_t*互轉 及 A2T, T2A巨集及其實現原理

char*, wchat_t*互轉 及 A2T, T2A巨集及其實現原理

char :單位元組變數型別,表示ASCII碼。

wchar_t :寬位元組變數型別,用於表示Unicode字元。在<string.h>定義為:typedef unsigned short wchar_t。

TCHAR: VS下的中間型別。在“使用Unicode字符集”下TCHAR定義為wchar_t,在字符集 “未設定” 條件下TCHAR定義為char。

A2T,及T2A是兩個非常有用的巨集,可以用於實現char*和wchar_t*字串之間的轉換。巨集的實現也將會在測試程式碼中給出,不感興趣的直接跳過。費話不多說,直接上測試程式碼,參考程式碼註釋。

// demo1.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"

#include <iostream>
#include <cstring>
using namespace std;
#include <atlbase.h>
#include <Windows.h>

void test_L_macro()
{ 
	char astr[] = "hello";
	cout<<"sizeof(astr):"<<sizeof(astr)<<endl
		<<"strlen(astr):"<<strlen(astr)<<endl;


	//L"str"表示將ANSI字串轉換成unicode的字串,就是每個字元佔用兩個位元組。
	wchar_t wstr[] = L"hello"; //typedef unsigned short wchar_t
	cout<<"sizeof(wstr)"<<sizeof(wstr)<<endl
		<<"wcslen(wstr):"<<wcslen(wstr)<<endl;
}


void test_T_macro()
{
	/*
	#ifdef   _UNICODE
		#define __T(x)      L ## x
	#else
		#define __T(x)      x
	#endif


	#define _T(x)       __T(x)
	#define _TEXT(x)    __T(x)
	#define TEXT(quote) __TEXT(quote)


	#ifdef _UNICODE   
		typedef char TCHAR;   
	#else   
		typede wchar_t TCHAR;   
	#endif 
	*/
	//如果在程式中使用了TCHAR,那麼就不應該使用ANSI的strXXX函式或者Unicode的wcsXXX函數了,
	//而必須使用tchar.h中定義的_tcsXXX函式。
	TCHAR buf[] = _T("hello");
	cout<<"sizeof(buf):"<<sizeof(buf)<<endl
		<<"_tcslen(lpBuf):"<<_tcslen(buf)<<endl; 

	/*
	#ifdef _UNICODE   
		typedef wchar_t WCHAR;// wc,   16-bit UNICODE character
		typedef __nullterminated WCHAR *LPWSTR;
		typedef LPWSTR PTSTR, LPTSTR;
	#else   
		typedef char CHAR;
		typedef __nullterminated CHAR *LPSTR;
		typedef LPSTR LPTSTR;
	#endif 
	*/

	LPTSTR lpBuf = TEXT("hello");
	cout<<"_tcslen(lpBuf):"<<_tcslen(lpBuf)<<endl;  
}

void test_A2T()
{
	USES_CONVERSION;
	char *astr = "hello";
	LPTSTR wstr = A2T(astr);

#ifdef _UNICODE
	wcout<<"wcout\<\<wstr:"<<wstr<<endl;
#else
	cout<<"cout\<\<wstr:"<<wstr<<endl;
#endif
}

void test_A2T_()
{
	int _convert = 0;
	(_convert); 
	UINT _acp = ATL::_AtlGetConversionACP() ; 
	(_acp); 
	LPCWSTR _lpw = 0; 
	(_lpw); 
	LPCSTR _lpa = 0; 
	(_lpa);

	char *astr = "hello";

	LPTSTR wstr = ( ((_lpa = astr) == 0) ? 0 : ( _convert = (lstrlenA(_lpa)+1), (2147483647/2<_convert)? 0 : AtlA2WHelper((LPWSTR) _alloca(_convert*sizeof(WCHAR)), _lpa, _convert, _acp)));
	//p.s. AtlA2WHelper呼叫了函式MultiByteToWideChar
	//_alloca函式用於在棧上分配記憶體,參考:http://msdn.microsoft.com/en-us/library/wb1s57t5.aspx

	wcout<<"wcout\<\<wstr:"<<wstr<<endl;

}

void test_T2A()
{
	USES_CONVERSION;	
	LPTSTR wstr = _T("hello");
	char *astr = T2A(wstr);

	cout<<"cout\<\<astr:"<<astr<<endl;
}

void test_T2A_()
{
	int _convert = 0; 
	(_convert); 
	UINT _acp = ATL::_AtlGetConversionACP() ; 
	(_acp); 
	LPCWSTR _lpw = 0; 
	(_lpw); 
	LPCSTR _lpa = 0; 
	(_lpa);	

	LPTSTR wstr = L"hello";

	char *astr = ( ((_lpw = wstr) == 0) ? 0 : ( (_convert = (lstrlenW(_lpw)+1), (_convert>2147483647/2) ? 0 : AtlW2AHelper((LPSTR) _alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp))));
	//p.s. AtlW2AHelper呼叫了函式WideCharToMultiByte
	//_alloca函式用於在棧上分配記憶體,參考:http://msdn.microsoft.com/en-us/library/wb1s57t5.aspx

	cout<<"cout\<\<astr:"<<astr<<endl;
}

int main()
{
	test_L_macro();
	test_T_macro();

	test_A2T();
	test_A2T_();

	test_T2A();
	test_T2A_();
}

P.S.

test_A2T_ 是 test_A2T的巨集替換實現;test_T2A_ 是 test_T2A的巨集替換實現;