多字节与宽字节转换
参考博客:http://blog.csdn.net/luoweifu/article/details/49382969
多字节字符与宽字节字符
char与wchar_t
我们知道C++基本数据类型中表示字符的有两种:char、wchar_t。
char叫多字节字符,一个char占一个字节,之所以叫多字节字符是因为它表示一个字时可能是一个字节也可能是多个字节。一个英文字符(如’s’)用一个char(一个字节)表示,一个中文汉字(如’中’)用3个char(三个字节)表示,看下面的例子。
void TestChar()
{
char ch1 = 's'; // 正确
cout << "ch1:" << ch1 << endl;
char ch2 = '中'; // 错误,一个char不能完整存放一个汉字信息
cout << "ch2:" << ch2 << endl;
char str[4] = "中"; //前三个字节存放汉字'中',最后一个字节存放字符串结束符\0
cout << "str:" << str << endl;
//char str2[2] = "国"; // 错误:'str2' : array bounds overflow
//cout << str2 << endl;
}
wchar_t被称为宽字符,一个wchar_t占2个字节。之所以叫宽字符是因为所有的字都要用两个字节(即一个wchar_t)来表示,不管是英文还是中文。看下面的例子:
void TestWchar_t()
{
wcout.imbue(locale("chs")); // 将wcout的本地化语言设置为中文
wchar_t wch1 = L's'; // 正确
wcout << "wch1:" << wch1 << endl;
wchar_t wch2 = L'中'; // 正确,一个汉字用一个wchar_t表示
wcout << "wch2:" << wch2 << endl;
wchar_t wstr[2] = L"中"; // 前两个字节(前一个wchar_t)存放汉字'中',最后两个字节(后一个wchar_t)存放字符串结束符\0
wcout << "wstr:" << wstr << endl;
wchar_t wstr2[3] = L"中国";
wcout << "wstr2:" << wstr2 << endl;
}
char与wchar_t 的相关转换
宽字节转多字节
//计算需要多少个字节才能表示对应的多字节字符串
DWORD num=WideCharToMultiByte(CP_ACP,0,pWCHAR,-1,NULL,0,NULL,0);
//开辟空间
char *pChar=NULL;
pChar=(char*)malloc(num*sizeof(char));
if (pChar==NULL)
{
free(pChar);
}
memset(pChar,0,num*sizeof(char));
//将宽字节字符串转换为多字节字符串
WideCharToMultiByte(CP_ACP,0,pWCHAR,-1,pChar,num,NULL,0);
多字节转换为宽字节
wchar_t* pWCHAR=NULL;
//计算pChar所指向的多字节字符串相当于多少个宽字节
DWORD num=MultiByteToWideChar(CP_ACP,0,pChar,-1,NULL,0);
pWCHAR=(wchar_t*)malloc(num*sizeof(wchar_t));
if (pWCHAR==NULL)
{
free(pWCHAR);
}
memset(pWCHAR,0,num*sizeof(wchar_t));
//多字节转换为宽字节
MultiByteToWideChar(CP_ACP,0,pChar,-1,pWCHAR,num);
string与wstring
字符数组可以表示一个字符串,但它是一个定长的字符串,我们在使用之前必须知道这个数组的长度。为方便字符串的操作,STL为我们定义好了字符串的类string和wstring。大家对string肯定不陌生,但wstring可能就用的少了。
string是普通的多字节版本,是基于char的,对char数组进行的一种封装。
wstring是Unicode版本,是基于wchar_t的,对wchar_t数组进行的一种封装。
string 与 wstring的相关转换:
以下的两个方法是跨平台的,可在Windows下使用,也可在Linux下使用。
#include <cstdlib>
#include <string.h>
#include <string>
// wstring => string
std::string WString2String(const std::wstring& ws)
{
std::string strLocale = setlocale(LC_ALL, "");
const wchar_t* wchSrc = ws.c_str();
size_t nDestSize = wcstombs(NULL, wchSrc, 0) + 1;
char *chDest = new char[nDestSize];
memset(chDest,0,nDestSize);
wcstombs(chDest,wchSrc,nDestSize);
std::string strResult = chDest;
delete []chDest;
setlocale(LC_ALL, strLocale.c_str());
return strResult;
}
// string => wstring
std::wstring String2WString(const std::string& s)
{
std::string strLocale = setlocale(LC_ALL, "");
const char* chSrc = s.c_str();
size_t nDestSize = mbstowcs(NULL, chSrc, 0) + 1;
wchar_t* wchDest = new wchar_t[nDestSize];
wmemset(wchDest, 0, nDestSize);
mbstowcs(wchDest,chSrc,nDestSize);
std::wstring wstrResult = wchDest;
delete []wchDest;
setlocale(LC_ALL, strLocale.c_str());
return wstrResult;
}
理解_T()、_Text()宏即L””
上一小节对MessageBox的调用中除了使用L”Title”外,还可以使用_T(“Title”)和_TEXT(“Title”)。而且你会发现在MFC和Win32程序中会更多地使用_T和_TEXT,那_T、_TEXT和L之间有什么区别呢?
通过第一小节多字节字符与宽字节字符我们知道表示多字节字符(char)串常量时用一般的双引号括起来就可以了,如”String test”;而表示宽字节字符(wchar_t)串常量时要在引号前加L,如L”String test”。
查看tchar.h头文件的定义我们知道_T和_TEXT的功能是一样的,是一个预定义的宏。
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
我们再看看__T(x)的定义,发现它有两个:
#ifdef _UNICODE
// ... 省略其它代码
#define __T(x) L ## x
// ... 省略其它代码
#else /* ndef _UNICODE */
// ... 省略其它代码
#define __T(x) x
// ... 省略其它代码
#endif /* _UNICODE */
当我们的工程的Character Set设置为Use Unicode Character Set时_T和_TEXT就会在常量字符串前面加L,否则(即Use Multi-Byte Character Set时)就会以一般的字符串处理。
相互转换方法:
LPWSTR->LPTSTR: W2T();
LPTSTR->LPWSTR: T2W();
LPCWSTR->LPCSTR: W2CT();
LPCSTR->LPCWSTR: T2CW();
ANSI->UNICODE: A2W();
UNICODE->ANSI: W2A();
相关博客:
c++中char*\wchar_t*\string\wstring之间的相互转换:(URL编码、解码和字符串替换的函数)http://blog.csdn.net/mfcing/article/details/7529848