MultiByte与WideChar之间的转化

来源:互联网 发布:mac无法切换大小写 编辑:程序博客网 时间:2024/06/06 00:19

遇到这样一个问题,程序使用的是Unicode编码,从Edit中读取出来的Cstring内容直接存储到txt文件中会出现乱码。

txt使用的ANSI编码,而Edit空间中的内容是Unicode编码,所以会出现乱码。


百度一下才知道,编译器的库函数中存在Unicode与ANSI之间相互转化的函数。




1. ANSI转化为Unicode

MultiByteToWideChar 这个函数将ANSI转化为Unicode

原函数:

int MultiByteToWideChar(

UINT CodePage,

DWORD dwFlags,

LPCSTR lpMultiByteStr,

int cchMultiByte,

LPWSTR lpWideCharStr,

int cchWideChar

);

参数说明:

CodePage参数标识了与多字节字符串关联的一个代码页值。我自己理解就是要转化成的字符串的编码方式。

dwFlags参数允许我们进行额外的控制,它会影响带变音符号(比如重音)的字符,但是,一般情况下不使用这个标识,所以传给dwFlags的值是0。

lpMultiByteStr参数指定要转换的字符串。

cchMultiByte参数指定字符串的长度(字节数)。如果传给cchMultiByte的参数值是-1,函数便可自动判断源字符串的长度。

lpWideCharStr参数指定的是一个内存缓冲区的地址,缓冲区的内容是转换后的Unicode版本的字符串。

cchWideChar参数指定缓冲区的最大长度(字符数)

一般按照以下步骤将一个多字节字符串转化为Unicode形式

(1)调用MultiByteToWideChar,为lpWideCharStr参数传入NULL,为cchWideChar参数传入0,为cchMultiByte参数传入-1。

(2)分配一块足以容纳转换后的unicode字符串的内存。它的大小是上一个MultiByteToWideChar调用的返回值乘以sizeof(wchar_t)

(3)再次调用MultiByteToWideChar,这一次将缓冲区作为lpWideCharStr参数的传入值,将第一次MultiByteToWideChar调用的返回值乘以sizeof(wchar_t)得到的大小作为cchWideChar参数的传入值。

(4)使用转换后的字符串。

(5)释放Unicode字符串占用的内存。

下面是一个简单的例子:

LPCSTR strMulti = "鎯呭喌?";int iNum = MultiByteToWideChar(CP_UTF8, 0, strMulti, -1, NULL, 0);LPWSTR pUniCode = new WCHAR[sizeof(wchar_t) * iNum];MultiByteToWideChar(CP_UTF8, 0, strMulti, -1, pUniCode, sizeof(wchar_t) * iNum );delete []pUniCode;

最后pUniCode的结果是UTF8编码的“情况?”




2. Unicode转化为ANSI

WideCharToMultiByte 这个函数将Unicode转化为ANSI

函数原型:

int WideCharToMultiByte(

UINT CodePage,

DWORD dwFlags,

LPCWSTR lpWideCharStr,

int cchWideChar,

LPSTR lpMultiByteStr,

int cchMultiByte,

LPCSTR lpDefaultChar,

LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE

);


参数说明:

CodePage参数标识了要与新转换的字符串关联的代码页,代码页包含如下几个值:


dwFlags参数允许我们指定额外的转化控制,这些标志会影响带变音符号的字符和系统不能转换的字符。但是我们一般不需要这种转换,所以传入参数设置为0

lpWideCharStr参数指定要转换字符串的内存地址。

cchWideChar参数指出该字符串的长度(字符数),如果此参数传入-1,由函数来判断字符串的长度。

lpMultiByteStr参数指向转换后字符串的缓存区地址。

cchMultiByte参数中指定此缓存的最大值(字节数)。如果将其设置为0,将会返回目标缓存区需要的大小。

这个函数与上面函数的主要区别是,无需在进行乘法运算,它返回的目标缓存区的大小就是所需的字节数。

注意:此函数比上面的函数参数要多两个,分别是lpDefaultChar、pfUsedDefaultChar。只有一个字符在uCodePage指定的代码页中没有对应的表示时,WideCharToMultiByte函数才会使用这两个参数,在遇到一个不能转换的宽字符时,函数便使用lpDefaultChar参数指向的字符。如果这两个参数为NULL,函数会使用系统默认的字符。这个默认字符通常是一个问号。这对文件名来说非常危险,因为问号是一个通配符。pfUsedDefaultChar参数指向一个布尔变量,在宽字符字符串中,如果至少有一个字符不能转换为对应的多字节形式,函数就会把这个变量设置为TRUE,如果所有字符都能成功转化,就会把这个变量设置为FALSE,我们可以在函数返回后测试该变量,验证宽字符串是否已经转化成功,同样,我们可以通过此参数传入NULL值。

DWORD dwNum = WideCharToMultiByte(CP_ACP,NULL,strText,-1,NULL,0,NULL,FALSE);char *psText;psText = new char[dwNum];WideCharToMultiByte (CP_ACP, NULL, strText,-1, psText,dwNum,NULL,FALSE);delete []psText;



0 0
原创粉丝点击