char与wchar_t之间的转换

char*与wchar_t*之间的转换

1.问题描述

char字符与wchar_t字符由于编码不同,所以在char*和wchar_t之间使用强制类型转换达不到正确转换字符串的目的。考察如下程序。 #include usingnamespace std;

int main(){ }

wchar_t* str=L\我们\; char* s=(char*)str; cout<

输出结果出错:只输出A。经过强制类型转换,s指向了宽字符编码字符串,字符串数据没有发生任何变化,只是用多字节字符字符编码重新对它进行解释,自然输出的结果是错误的。

2.char*与wchar_t*之间相互转换

要想将宽字符编码字符串转换成多字节编码字符串(或者反过来),必须先读懂原来的字符串,然后再重新对它进行编码。只有这样才能到达转换的目的。由于宽字符可以表示多国语言的文字,因此,下文的讨论限于中文的宽字符串与多字节字符串之间的相互转换。在不同的才做系统上,有一些特殊的库函数可以用来进行字符编码之间的转换。在VC++中,其中关键的几个函数是setlocale()、wcstombs_s()和mbstowcs_s()。 2.1关键函数简介

(1)setlocale()

功能:配置地域化信息 头文件:#include

函数原型:char *setlocale (int category, const char * locale); 函数参数:

category表示对本地化的某项内容进行设置,可取如下值: LC_ALL 包括下面的全部选项都要; LC_COLLATE 配置字符串比较;

C_CTYPE 配置字符类别及转换,例如全变大写 strtoupper(); LC_MONETARY 配置金融货币; LC_NUMERIC 配置小数点后的位数;

LC_TIME 配置时间日期格式,与 strftime() 合用。 locale表示本地域代号: 如果为NULL,则返回当前的locale名称(一般为C);如果非空,则根据category和locale进行设置,如果成功,则返回新的locale名称(地域名称),如果失败,则返回 NULL。

(2)wcstombs_s()

功能:将宽字符编码字符串转换成多字节编码字符串 头文件:#include

函数原型:errno_t__cdecl wcstombs_s(size_t * _PtNumOfCharConverted, char * _Dst, size_t _DstSizeInBytes, constwchar_t * _Src, size_t _MaxCountInBytes); 函数参数:

PtNumOfCharConverted:指向转换后的字符串的长度加上结束符(单位字节); Dst:指向转换后的字符串首地址;

DstSizeInBytes:目的地址最大字节空间(单位字节); _Src:源宽字符串首地址;

_MaxCountInBytes:最多可存入多字节字符串缓冲最的字节数,用于裁剪转换后的字符串。 返回值:成功返回0,失败则返回失败代码。

(3)mbstowcs_s ()

函数功能:将多字节编码字符串转换成宽字符编码字符串 头文件:#include 函数原型:

errno_t__cdecl mbstowcs_s(size_t * _PtNumOfCharConverted, wchar_t * _DstBuf, _SizeInWords, constchar * _SrcBuf, size_t _MaxCount ); 参数说明:

PtNumOfCharConverted:指向转换后的字符串的长度加上结束符(单位wchar_t); _DstBuf:指向转换后的字符串首地址;

_SizeInWords:目的地址最大字空间大小(单位wchar_t); _SrcBuf:源多字节字符串首地址;

_MaxCount:最多可存入宽字符串缓冲中的字符个数,用于裁剪转换后的宽字符串。 返回值:成功返回0,失败则返回失败代码。

2.2转换实例 #include #include #include usingnamespace std;

string ws2s(constwstring&ws){ size_t convertedChars=0;

string curLocale=setlocale(LC_ALL,NULL); //curLocale=\ setlocale(LC_ALL,\); constwchar_t* wcs=ws.c_str();

size_t dByteNum=sizeof(wchar_t)*ws.size()+1; cout<<\<

//5

char* dest=newchar[dByteNum];

wcstombs_s(&convertedChars,dest,dByteNum,wcs,_TRUNCATE); cout<<\<

setlocale(LC_ALL,curLocale.c_str()); return result;

}

size_t wstring s2ws(conststring&s){ }

int main(){ }

程序输出: ABC我们 ABC我们

程序运行结果表明,char*到wchar_t*的双向转换时成功的,但要注意的是,执行转换的函数mbstowcs_s和wcstombs_s的运行是依赖于当前的locale设置。在程序中去除相关的setlocale()函数调用,就得不到正确的结果。

3.利用Windows API实现字符编码的转换

#include #include usingnamespace std;

int main(){

wchar_t* ws=L\测试字符串\;

除了可以利用C/C++库函数解决字符编码的转换问题,还可以利用特定操作系统下提供的函数。例如,可以利用Windows API实现字符编码的转换。考察如下程序。

wchar_t* wstr=L\我们\; char* str=\我们\; string obj=ws2s(wstr); cout<

setlocale(LC_ALL, \); //或者wcout.imbue(locale(\ wstring objw=s2ws(str); wcout<

wchar_t* dest=newwchar_t[charNum];

mbstowcs_s(&convertedChars,dest,charNum,source,_TRUNCATE); cout<<\<

setlocale(LC_ALL,curLocale.c_str()); return result;

size_t convertedChars=0;

string curLocale=setlocale(LC_ALL,NULL); //curLocale=\ setlocale(LC_ALL,\); constchar* source=s.c_str();

size_t charNum=sizeof(char)*s.size()+1; cout<<\<

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4