第一个就是宽字符到多字节字符转换函数,函数原型如下:

int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar
);

此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:

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 

我想最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。

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 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol) 
对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。

lpWideCharStr: 待转换的宽字符串。 
cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。 
lpMultiByteStr: 接收转换后输出新串的缓冲区。 
cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。 
lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。 
lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。 
返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需 
字节数。函数失败,返回0。 

注意:函数WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。我的方法是先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区,详见下面的代码。另外,从Unicode UTF16向非Unicode字符集转换可能会导致数据丢失,因为该字符集可能无法找到表示特定Unicode数据的字符。

wchar_t* pwszUnicode = "Holle, word! 你好,中国! ";
int iSize;
char* pszMultiByte;
iSize = WideCharToMultiByte(CP_ACP, , pwszUnicode, -, NULL, , NULL, NULL);
pszMultiByte = (char*)malloc((iSize+)/**sizeof(char)*/);
WideCharToMultiByte(CP_ACP, , pwszUnicode, -, pszMultiByte, iSize, NULL, 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 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol) 
对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。 
以下函数我没用过,只简要说明之。 
int GetTextCharset( HDC hdc ); 
此函数获取当前选进的设备描述表的字符集,等同于GetTextCharsetInfo(hdc, NULL, 0)。 
返回值: 成功返回字符集标识,失败返回DEFAULT_CHARSET。

为了支持Unicode编码,需要多字节与宽字节之间的相互转换。这两个系统函数在使用时需要指定代码页。

  WideCharToMultiByte的代码页用来标记与新转换的字符串相关的代码页。
  MultiByteToWideChar的代码页用来标记与一个多字节字符串相关的代码页。
常用的代码页由CP_ACP和CP_UTF8两个:
  使用CP_ACP代码页就实现了ANSI与Unicode之间的转换。
  使用CP_UTF8代码页就实现了UTF-8与Unicode之间的转换。
1. ANSI to Unicode

wstring ANSIToUnicode( const string& str )
{
int len = ;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,
,
str.c_str(),
-,
NULL,
);
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+];
memset(pUnicode,,(unicodeLen+)*sizeof(wchar_t));
::MultiByteToWideChar( CP_ACP,
,
str.c_str(),
-,
(LPWSTR)pUnicode,
unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}

2. Unicode to ANSI

string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,
,
str.c_str(),
-,
NULL,
,
NULL,
NULL );
pElementText = new char[iTextLen + ];
memset( ( void* )pElementText, , sizeof( char ) * ( iTextLen + ) );
::WideCharToMultiByte( CP_ACP,
,
str.c_str(),
-,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}

3. UTF-8 to Unicode

wstring UTF8ToUnicode( const string& str )
{
int len = ;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,
,
str.c_str(),
-,
NULL,
);
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+];
memset(pUnicode,,(unicodeLen+)*sizeof(wchar_t));
::MultiByteToWideChar( CP_UTF8,
,
str.c_str(),
-,
(LPWSTR)pUnicode,
unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}

4. Unicode to UTF-8

string UnicodeToUTF8( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,
,
str.c_str(),
-,
NULL,
,
NULL,
NULL );
pElementText = new char[iTextLen + ];
memset( ( void* )pElementText, , sizeof( char ) * ( iTextLen + ) );
::WideCharToMultiByte( CP_UTF8,
,
str.c_str(),
-,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText; }

MULTIBYTETOWIDECHAR的与WIDECHARTOMULTIBYTE的参数详解及相互转换的更多相关文章

  1. Nginx主配置参数详解,Nginx配置网站

    1.Niginx主配置文件参数详解 a.上面博客说了在Linux中安装nginx.博文地址为:http://www.cnblogs.com/hanyinglong/p/5102141.html b.当 ...

  2. iptables参数详解

    iptables参数详解 搬运工:尹正杰 注:此片文章来源于linux社区. Iptalbes 是用来设置.维护和检查Linux内核的IP包过滤规则的. 可以定义不同的表,每个表都包含几个内部的链,也 ...

  3. chattr的常用参数详解

    chattr的常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际生产环境中,有的运维工程师不得不和开发和测试打交道,在我们公司最常见的就是部署接口.每天每个人部署的 ...

  4. mha配置参数详解

    mha配置参数详解: 参数名字 是否必须 参数作用域 默认值 示例 hostname Yes Local Only - hostname=mysql_server1, hostname=192.168 ...

  5. $.ajax()方法所有参数详解;$.get(),$.post(),$.getJSON(),$.ajax()详解

    [一]$.ajax()所有参数详解 url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注 ...

  6. linux PHP 编译安装参数详解

    linux PHP 编译安装参数详解 ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc -- ...

  7. 【转】jqGrid 各种参数 详解

      [原文]http://www.cnblogs.com/younggun/archive/2012/08/27/2657922.htmljqGrid 各种参数 详解 JQGrid JQGrid是一个 ...

  8. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  9. mysql5.6主从参数详解

    mysql5.6的主从相当的不错,增加了不少参数,提升了主从同步的安全和效率,以下是mysql5.6主从参数详解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

随机推荐

  1. wordpress主题结构_源码

    WordPress博客主题的工作机制 WordPress主题由一系列模板文件组成,每个文件分别控制主题的特定区域.无论你处于哪个页面都能看到的网站的静态部分,由header文件.sidebar和foo ...

  2. iphone Dev 开发实例10:How To Add a Slide-out Sidebar Menu in Your Apps

    Creating the Xcode Project With a basic idea about what we’ll build, let’s move on. You can create t ...

  3. (C#) What is the difference between "const" and "static readonly" ?

    const int a must be initialized initialization must be at compile time readonly int a can use defaul ...

  4. Linux命令(17)du 查看文件和目录磁盘使用情况

    Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能 ...

  5. pedagogical

    在线考试     // '+this+''; }); //alert(错了); $("#ans").html(html); } function clk(obj){ var inp ...

  6. activity属性_ _activity 属性说明

    activity是android中使用非常平凡的一种组件,我们除了需要掌握activity中的生命周期以外,还需要掌握activity中的其 他设置. 1.activity 中主题的设置   andr ...

  7. ylbtech-Unitity-CS-Arrays:数组

    ylbtech-Unitity-CS-Arrays:数组 1.A,效果图返回顶部   1.B,源代码返回顶部 1.B.1, using System; class DeclareArraysSampl ...

  8. 模拟实现兼容低版本IE浏览器的原生bind()函数功能

    模拟实现兼容低版本IE浏览器的原生bind()函数功能: 代码如下: if(!Function.prototype.bind){   Function.prototype.bind=function( ...

  9. GCD信号量并发控制

    /** *  当我们在处理一系列线程的时候,当数量达到一定量,在以前我们可能会选择使用NSOperationQueue来处理并发控制,但如何在GCD中快速的控制并发呢?答案就是dispatch_sem ...

  10. WCF bindings comparison z

    Binding Protocol/Transport Message Encoding Security Default Session Transaction Duplex BasicHttpBin ...