各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar_第1页
各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar_第2页
各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar_第3页
各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar_第4页
各种字符编码间的转换方法:MultiByteToWideChar和MultiByteToWideChar_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

MultiByteToWideChar和MultiByteToWideChar对各种字符编码间的转换函数原型:int WideCharToMultiByte(UINT CodePage,DWORD dwFlags,LPCWSTR lpWideCharStr,int cchWideChar,LPSTR lpMultiByteStr,int cbMultiByte,LPCSTR lpDefaultChar,LPBOOL lpUsedDefaultChar);此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。参数说明:1、CodePage指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,可选择以下代码页:CP_ACP /当前系统ANSI代码页 CP_MACCP /当前系统Macintosh代码页 CP_OEMCP /当前系统OEM代码页,一种原始设备制造商硬件扫描码 CP_SYMBOL /Symbol代码页,用于Windows 2000及以后版本 CP_THREAD_ACP /当前线程ANSI代码页,用于Windows 2000及以后版本 CP_UTF7 /UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL CP_UTF8 /UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL 用 GetLocaleInfo 函数获取当前系统的代码页,936: 简体中文, 950: 繁体中文,949:韩文2、dwFlags 一般用 0 就可以了 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符: MB_PRECOMPOSED /总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用MB_COMPOSITE /总是使用分解字符,即总是使用基字符+不占空间字符的方式MB_ERR_INVALID_CHARS /设置此选项,函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符MB_USEGLYPHCHARS /使用像形字符代替控制字符3、lpMultiByteStr /要转换的字符串4、cbMultiByte /要转换字符串的长度,-1表示转换到字符串结尾。返回原字符串长度。0 作为结束符的字符串5、lpWideCharStr/接收转换后输出的宽字符串的缓冲,如果为 NULL, 就是代表计算生成的字符串的长度。6、cchWideChar/输出缓冲区大小,转化生成的 unicode 字符串缓存的容量。如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不同 为0表示调用失败;当cchWideChar为0时,函数将返回所需缓冲区大小int BufSize = MultiByteToWideChar(936,0,s,-1,NULL,0); /计算简体中文字符串 s 转成 widestring 之后占用的内存字节数 /在此处为 wsbuf 分配内存 BufSize 个字节MultiByteToWideChar(936,0,s,-1,wsbuf,BufSize); /把简体中文字符串 s 转化为 unicode 的 WideString最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。例一:Unicode转换到GBK#include #define CODE_PAGE_GB18030 54936int Unicode2GBK( wchar_t *pUnicode, char* ppDest) / get the size of the dest stringconst int size = :WideCharToMultiByte( CODE_PAGE_GB18030, 0/* you can do more for it*/,pUnicode, -1, 0, 0, 0, 0 );if ( size = 0 ) return -1; char* pDestString = new charsize + 2;:memset( pDestString, 0, sizeof(pDestString) );/ transformint ret = :WideCharToMultiByte( CODE_PAGE_GB18030, 0, pUnicode, -1, pDestString, size, 0, 0 );if( ret = 0 ) delete pDestString; return -1; else *ppDest = pDestString; return 0; 例二:字串转换wchar_t* pwszUnicode = Holle, word! 你好,中国! ;int iSize;char* pszMultiByte;iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL);pszMultiByte = (char*)malloc(iSize+1)/*sizeof(char)*/);WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);注意事项:dwFlags: 指定如何处理没有转换的字符, 但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示:WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。 WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK一起使用 WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,与WC_COMPOSITECHECK一起使用 WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如?),与WC_COMPOSITECHECK一起使用。 当指定WC_COMPOSITECHECK时,函数会将合成字符转换成预制字符。合成字符由一个基字符和一个不占空间的字符(如欧洲国家及汉语拼音的音标)组成,每一个都有不同的字符值。预制字符有一个用于表示基字符和不占空间字符的合成体的单一的字符值。 当指定WC_COMPOSITECHECK选项时,也可以使用上表列出的最后3个选项来定制预制字符的转换规则。这些选项决定了函数在遇到宽字符串的合成字符没有对应的预制字符时的行为,他们与WC_COMPOSITECHECK一起使用,如果都没有指定,函数默认WC_SEPCHARS。 对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。50220 5022150222 50225 50227 50229 52936 54936 57002到5701165000(UTF7) 42(Symbol) 对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags 而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。第二个是多字节字符到宽字符转换函数,函数原型如下: int MultiByteToWideChar(UINT CodePage,DWORD dwFlags,LPCSTR lpMultiByteStr,int cbMultiByte,LPWSTR lpWideCharStr,int cchWideChar);此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。此函数的参数,返回值及注意事项参见上面函数WideCharToMultiByte的说明,这里只对dwFlags做简单解释。dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。 MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用 MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式 MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码 ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符 MB_USEGLYPHCHARS 使用像形字符代替控制字符 对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。50220 5022150222 50225 50227 50229 52936 54936 57002到5701165000(UTF7) 42(Symbol)对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。 以下函数我没用过,只简要说明之。int GetTextCharset( HDC hdc );此函数获取当前选进的设备描述表的字符集,等同于GetTextCharsetInfo(hdc, NULL, 0)。返回值: 成功返回字符集标识,失败返回DEFAULT_CHARSET。1.使用方法详解在本文开始之处,先简要地说一下何为短字符和宽字符.所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:windows 程序设计,windows 核心编程.这两本书关于这两种字符都有比较详细的解说.宽字符转换为多个短字符是一个难点,不过我们只要掌握到其中的要领,便可如鱼得水.好吧,那就让我们开始吧.这个是我们需要转化的多字节字符串:char sText20 = 多字节字符串!OK!;我们需要知道转化后的宽字符需要多少个数组空间.虽然在这个里程里面,我们可以直接定义一个20*2宽字符的数组,并且事实上将运行得非常轻松愉快.但假如多字节字符串更多,达到上千个乃至上万个,我们将会发现其中浪费的内存将会越来越多.所以以多字节字符的个数的两倍作为宽字符数组下标的声明绝对不是一个好主意.所幸,我们能够确知所需要的数组空间。我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数:DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0); 接下来,我们只需要分配响应的数组空间:wchar_t *pwText;pwText = new wchar_tdwNum;if(!pwText) delete pwText; 接着,我们就可以着手进行转换了.在这里以转换成ASCII码做为例子:MultiByteToWideChar (CP_ACP, 0, psText, -1, sText, dwSize);最后,使用完毕当然要记得释放占用的内存:delete psText;同理,宽字符转为多字节字符的代码如下:wchar_t wText20 = L宽字符转换实例!OK!;DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);char *psText;psText = new chardwNum;if(!psText) delete psText; WideCharToMultiByte (CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);delete psText; 如果之前我们已经分配好空间,并且由于字符串较短,可以不理会浪费的空间,仅仅只是想简单地将短字符和宽字符相互转换,那有没有什么简便的方法呢? WIN32 API里没有符合这种要求的函数,但我们可以自己进行封装:BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)DWORD dwMinSize;dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);if(dwSize dwMinSize) return FALSE; MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);return TRUE;BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)DWORD dwMinSize;dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);if(dwSize Setting. - locale - default language ,选择中文,然后编译即可.Windows CE:不支持参数CodePage中的CP_UTF7和CP_UTF8的值,以及参数dwFlags中的WC_NO_BEST_FIT_CHARS值。速查:Windows NT 3.1、Windows 95以上、Windows CE 1.0以上,头文件:winnls.h;库文件:kernel32.lib。参考代码:/GB2312 转换成 Unicode:wchar_t* GB2312ToUnicode(const char* szGBString) UINT nCodePage = 936; /GB2312 int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0); wchar_t* pBuffer = new wchar_tnLength+1; MultiByteToWideChar(nCodePage,0,szGBString,-1,pBuffer,nLength); pBuffernLength=0; return pBuffer;/BIG5 转换成 Unicode:wchar_t* BIG5ToUnicode(const char* szBIG5String) UINT nCodePage = 950; /BIG5 int nLength=MultiByteToWideChar(nCodePage,0,szBIG5String,-1,NULL,0); wchar_t* pBuffer = new wchar_tnLength+1; MultiByteToWideChar(nCodePage,0,szBIG5String,-1,pBuffer,nLength); pBuffernLength=0; return pBuffer;/Unicode 转换成 GB2312:char* UnicodeToGB2312(const wchar_t* szUnicodeString) UINT nCodePage = 936; /GB2312 int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL); char* pBuffer=new charnLength+1; WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL); pBuffernLength=0; return pBuffer;/Unicode 转换成 BIG5:char* UnicodeToBIG5(const wchar_t* szUnicodeString) UINT nCodePage = 950; /BIG5 int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL); char* pBuffer=new charnLength+1; WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL); pBuffernLength=0; return pBuffer;/繁体中文BIG5 转换成 简体中文 GB2312char* BIG5ToGB2312(const char* szBIG5String)LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC); wchar_t* szUnicodeBuff = BIG5ToUnicode(szBIG5String); char* szGB2312Buff = UnicodeToGB2312(szUnicodeBuff); int nLength = LCMapString(lcid,LCMAP_SIMPLIFIED_CHINESE, szGB2312Buff,-1,NULL,0); char* pBuffer = new charnLength + 1; LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE,szGB2312Buff,-1,pBuffer,nLength); pBuffernLength = 0; delete szUnicodeBuff; delete szGB2312Buff; return pBuffer;/简体中文 GB2312 转换成 繁体中文BIG5char* GB2312ToBIG5(const char* szGBString)LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC); int nLength = LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,NULL,0); char* pBuffer=new charnLength+1; LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,pBuffer,nLength); pBuffernLength=0; wchar_t* pUnicodeBuff = GB2312ToUnicode(pBuffer); char* pBIG5Buff = UnicodeToBIG5(pUnicodeBuff); delete pBuffer; delete pUnicodeBuff; return pBIG5Buff;/string转换为wstring:string str=_T(翔翔糖糖);int size=MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,NULL,0);wchar_t *ch=new wchar_tsize+1;if(!MultiByteToWideChar(CP_ACP,0,str.c_str(),-1,ch,size) return false;wstring wstr=ch;/char*转换为wchar_t*:char *str=_T(翔翔糖糖);int size=MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);wchar_t *ch=new wchar_tsize+1;if(!MultiByteToWideChar(CP_ACP,0,str,-1,ch,size) return false;MultiByteToWideChar使用例子char* OleDBCom:UnsignedShortToCharp(unsigned short *strU)UINT nStrULength=WideCharToMultiByte(CP_ACP,0,strU,-1,NULL,NULL,NULL,NULL);LPSTR lpStr;lpStr=(char*)malloc(nStrULength);WideCharToMultiByte(CP_ACP,0,strU,-1,lpStr,nStrULength,NULL,NULL);return lpStr;unsigned short* OleDBCom:CharpToUnsignedShort(LPSTR str)OLECHAR strU255;int nStatus=MultiByteToWideChar(CP_ACP,0,str,-1,strU,255);return strU;HRESULT _fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW) ULONG cCharacters; DWORD dwError; if (NULL = pszA) *ppszW = NULL; return NOERROR; cCharacters = strlen(pszA)+1; *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2); if (NULL = *ppszW) return E_OUTOFMEMORY; if (0 = MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters, *ppszW, cCharacters) dwError = GetLastError(); CoTaskMemFree(*ppszW); *ppszW = NULL; return HRESULT_FROM_WIN32(dwError); return NOERROR;这里有个例子,PWSTR pWideCharStr;int nLenOfWideCharStr;首先计算需要的宽字符串的字符数nLenOfWideCharStr=MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,NULL,0)这里的pMultiByteStr是要转换的多字节字符。给pWideCharStr分配内存块pWideCharStr=HeapAlloc(GetProcessHeap(),0,nLenOfWideCharStr*sizeof(WCHAR);然后把多字节字符串转换成宽字符串MultiByteToWideChar(CP_ACP,0,pMultiByteStr,-1,pWideCharStr,nLenOfWideCharStr)WideCharToMultiByte和MultiByteToWideChar函数的用法为了支持Unicode编码,需要多字节与宽字节之间的相互转换。这两个系统函数在使用时需要指定代码页,在实际应用过程中遇到乱码问题,然后重新阅读Windows核心编程,总结出正确的用法。WideCharToMultiByte的代码页用来标记与新转换的字符串相关的代码页。MultiByteToWideChar的代码页用来标记与一个多字节字符串相关的代码页。常用的代码页由CP_ACP和CP_UTF8两个。使用CP_ACP代码页就实现了ANSI与Unicode之间的转换。使用CP_UTF8代码页就实现了UTF-8与Unicode之间的转换。下面是代码实现:1. ANSI to Unicodewstring ANSIToUnicode( const string& str )int len = 0;len = str.length();int unicodeLen = :MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, NULL, 0 );wchar_t * pUnicode;pUnicode = new ;memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t);:MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen );wstring rt;rt = ( wchar_t* )pUnicode;delete pUnicode;return rt;2. Unicode to ANSIstring UnicodeToANSI( const wstring& str )char* pElementText;int iTextLen;iTextLen = WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL );pElementText = new chariTextLen + 1;memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1) );:WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL );string strText;strText = pElementText;delete pElementText;return strText;3. UTF-8 to Unicodewstring UTF8ToUnicode( const string& str )int len = 0;len = str.length();int unicodeLen = :MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, NULL, 0 );wchar_t * pUnicode;pUnicode = new wchar_tunicodeLen+1;memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t);:MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen );wstring rt;rt = ( wchar_t* )pUnicode;delete pUnicode;return rt;4. Unicode to UTF-8string UnicodeToUTF8( const wstring& str )char* pElementText;int iTextLen;iTextLen = WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL );pElementText = new chariTextLen + 1;memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1) );:WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL );string strText;strText = pElementText;delete pElementText;return strText;#include stdafx.h#include string.h#include stdio.h#include windows.hint main(int argc, char* argv)char temp20;int nLen;LPWSTR name = LCPU;sprintf(temp,CPU%02d,i);nLen = MultiByteToWideChar(CP_ACP,0,temp,-1,NULL,0);MultiByteToWideChar(CP_ACP,0,temp,-1,(LPWSTR)name,nLen);WideCharToMultiByte(CP_ACP,0,(LPWSTR)name,-1, strs,100,NULL,NULL);printf(good: %s /n,name);return 0;调试时,在MultiByteToWideChar处报错MultiByteToWideChar 函数把一个字符串映射为一个宽字符串。被这个函数映射的字符串不必属于多字节字符集。 返回值:若该函数成功,且 cchMultiByte 为非零值,则返回值是写入由 lpWideCharStr 指向的缓冲区中的宽字符数。若该函数成功,且 cchMultiByte 为零,则返回值是以宽字符为单位的缓冲区大小值。该缓冲区可以接收转换后的字符串。若该函数失败,则返回值为FALSE,调用GetLastErro可获得补充的错误信息。1 /- /函数输入Big5字符,返回Gb简体字符 /两次转换

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论