1、把一个字符串(单字节char、多字节均可)转换为宽字符(UTF-16编码,双字节表示,在VC++程序中若选择Unicode编码,则使用的是双字节wchar_t)
函数原型:
- int MultiByteToWideChar(
- __in UINT CodePage,
- __in DWORD dwFlags,
- __in LPCSTR lpMultiByteStr,
- __in int cbMultiByte,
- __out_opt LPWSTR lpWideCharStr,
- __in int cchWideChar
- );
int MultiByteToWideChar(
__in UINT CodePage,
__in DWORD dwFlags,
__in LPCSTR lpMultiByteStr,
__in int cbMultiByte,
__out_opt LPWSTR lpWideCharStr,
__in int cchWideChar
);
CodePage --- 指出转换中使用的代码页,我的理解是指出源字符串的编码方式,以便进行转换,取值主要有:CP_ACP(ANSI编码,ASCII)、CP_MACCP(Macintosh上的编码)、CP_OEMCP(OEM编码页,可以打乱数据并且不可逆)、CP_SYMBOL(Symbol code page (42),MSDN也没具体说明...)、CP_THREAD_ACP(当前线程的windows ANSI编码)、CP_UTF7(仅用于强制7位传输机制下)、CP_UTF8(多字节编码,如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节。而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节,注:实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。所有其他的UNICODE字符转化成UTF-8将需要至少2个字节。)。
dwFlags --- 转换类型,我使用的时候,主要是char和utf8(3字节的)转换为wchar_t,所以直接将该参数置为0(对于以下编码页其值必须为0:50220、50221、50222、50225、50227、50229、57002 至 57011、65000 (UTF-7)、42 (Symbol)。对于UTF-8或者54936编码也 (GB18030,始于Windows Vista)须设为0或MB_ERR_INVALID_CHARS),未深究,其取值有MB_COMPOSITE、MB_ERR_INVALID_CHARS、MB_PRECOMPOSED(默认值)、MB_USEGLYPHCHARS。
lpMultiByteStr --- 指向待转换字符串的指针。
cbMultiByte --- cbMultiByte所指字符串的长度,以字节为单位。该参数不能设为0。如果该字符串是null结尾的,则可取值为-1,此时将处理整个字符串,所以转换后的双字节串也是null结尾的;若该参数设置为一个正整数,则只处理该参数指定的若干个字符,如果这些字符中不包含null,则转换后的双字节串不是null结尾,返回的长度也不包含该字符。
lpWideCharStr --- 接收转换后字符串的字符串指针(双字节的)。
cchWideChar --- lpWideCharStr所指字符串的长度,以字符为单位,若设为0,则函数返回转换需要的空间大小,单位是字符,不对lpWideCharStr做任何处理。
返回值:若成功则返回写入lpMultiByteStr中的字符的个数;若cchWideChar若设为0,则函数返回转换需要的空间大小,单位是字符;若源字符串无效,则返回相应的错误代码。
MSDN上的几个例子:
- /***************************/
- /* ansi-unicode conversion */
- /***************************/
- BOOL AnsiToUnicode16(CHAR *in_Src, WCHAR *out_Dst, INT in_MaxLen)
- {
- /* locals */
- INT lv_Len;
- // do NOT decrease maxlen for the eos
- if (in_MaxLen <= 0)
- return FALSE;
- // let windows find out the meaning of ansi
- // - the SrcLen=-1 triggers MBTWC to add a eos to Dst and fails if MaxLen is too small.
- // - if SrcLen is specified then no eos is added
- // - if (SrcLen+1) is specified then the eos IS added
- lv_Len = MultiByteToWideChar(CP_ACP, 0, in_Src, -1, out_Dst, in_MaxLen);
- // validate
- if (lv_Len < 0)
- lv_Len = 0;
- // ensure eos, watch out for a full buffersize
- // - if the buffer is full without an eos then clear the output like MBTWC does
- // in case of too small outputbuffer
- // - unfortunately there is no way to let MBTWC return shortened strings,
- // if the outputbuffer is too small then it fails completely
- if (lv_Len < in_MaxLen)
- out_Dst[lv_Len] = 0;
- else if (out_Dst[in_MaxLen-1])
- out_Dst[0] = 0;
- // done
- return TRUE;
- }
- BOOL AnsiToUnicode16L(CHAR *in_Src, INT in_SrcLen, WCHAR *out_Dst, INT in_MaxLen)
- {
- /* locals */
- INT lv_Len;
- // do NOT decrease maxlen for the eos
- if (in_MaxLen <= 0)
- return FALSE;
- // let windows find out the meaning of ansi
- // - the SrcLen=-1 triggers MBTWC to add a eos to Dst and fails if MaxLen is too small.
- // - if SrcLen is specified then no eos is added
- // - if (SrcLen+1) is specified then the eos IS added
- lv_Len = MultiByteToWideChar(CP_ACP, 0, in_Src, in_SrcLen, out_Dst, in_MaxLen);
- // validate
- if (lv_Len < 0)
- lv_Len = 0;
- // ensure eos, watch out for a full buffersize
- // - if the buffer is full without an eos then clear the output like MBTWC does
- // in case of too small outputbuffer
- // - unfortunately there is no way to let MBTWC return shortened strings,
- // if the outputbuffer is too small then it fails completely
- if (lv_Len < in_MaxLen)
- out_Dst[lv_Len] = 0;
- else if (out_Dst[in_MaxLen-1])
- out_Dst[0] = 0;
- // done
- return TRUE;
- }
/***************************/
/* ansi-unicode conversion */
/***************************/
BOOL AnsiToUnicode16(CHAR *in_Src, WCHAR *out_Dst, INT in_MaxLen)
{
/* locals */
INT lv_Len;
// do NOT decrease maxlen for the eos
if (in_MaxLen <= 0)
return FALSE;
// let windows find out the meaning of ansi
// - the SrcLen=-1 triggers MBTWC to add a eos to Dst and fails if MaxLen is too small.
// - if SrcLen is specified then no eos is added
// - if (SrcLen+1) is specified then the eos IS added
lv_Len = MultiByteToWideChar(CP_ACP, 0, in_Src, -1, out_Dst, in_MaxLen);
// validate
if (lv_Len < 0)
lv_Len = 0;
// ensure eos, watch out for a full buffersize
// - if the buffer is full without an eos then clear the output like MBTWC does
// in case of too small outputbuffer
// - unfortunately there is no way to let MBTWC return shortened strings,
// if the outputbuffer is too small then it fails completely
if (lv_Len < in_MaxLen)
out_Dst[lv_Len] = 0;
else if (out_Dst[in_MaxLen-1])
out_Dst[0] = 0;
// done
return TRUE;
}
BOOL AnsiToUnicode16L(CHAR *in_Src, INT in_SrcLen, WCHAR *out_Dst, INT in_MaxLen)
{
/* locals */
INT lv_Len;
// do NOT decrease maxlen for the eos
if (in_MaxLen <= 0)
return FALSE;
// let windows find out the meaning of ansi
// - the SrcLen=-1 triggers MBTWC to add a eos to Dst and fails if MaxLen is too small.
// - if SrcLen is specified then no eos is added
// - if (SrcLen+1) is specified then the eos IS added
lv_Len = MultiByteToWideChar(CP_ACP, 0, in_Src, in_SrcLen, out_Dst, in_MaxLen);
// validate
if (lv_Len < 0)
lv_Len = 0;
// ensure eos, watch out for a full buffersize
// - if the buffer is full without an eos then clear the output like MBTWC does
// in case of too small outputbuffer
// - unfortunately there is no way to let MBTWC return shortened strings,
// if the outputbuffer is too small then it fails completely
if (lv_Len < in_MaxLen)
out_Dst[lv_Len] = 0;
else if (out_Dst[in_MaxLen-1])
out_Dst[0] = 0;
// done
return TRUE;
}
2、把一个宽字符串(UTF-16编码,双字节表示)转换为多字节字符串(单字节char、多字节均可)
函数原型:
- int WideCharToMultiByte(
- __in UINT CodePage,
- __in DWORD dwFlags,
- __in LPCWSTR lpWideCharStr,
- __in int cchWideChar,
- __out_opt LPSTR lpMultiByteStr,
- __in int cbMultiByte,
- __in_opt LPCSTR lpDefaultChar,
- __out_opt LPBOOL lpUsedDefaultChar
- );
int WideCharToMultiByte(
__in UINT CodePage,
__in DWORD dwFlags,
__in LPCWSTR lpWideCharStr,
__in int cchWideChar,
__out_opt LPSTR lpMultiByteStr,
__in int cbMultiByte,
__in_opt LPCSTR lpDefaultChar,
__out_opt LPBOOL lpUsedDefaultChar
);
前6个参数同上,对于最后两个参数:
lpDefaultChar --- 若转换后的字符是目标字符集无法表示的,则用该字符代替,若设为NULL,则使用系统默认的字符(对于CP_UTF7和CP_UTF8,必须为NULL)。
lpUsedDefaultChar --- 这是一个输出参数,一个指示函数是否使用了默认字符来代替无法表示的字符的标志的指针(对于CP_UTF7和CP_UTF8,必须为NULL),若值为TRUE则表明存在无法表示的字符,反之则为FALSE;该参数可设为NULL。
lpDefaultChar lpUsedDefaultChar Result
NULL NULL 不做任何检查,此时函数效率最高
非空字符 NULL 使用用户指出的替代字符,但不设置lpUsedDefaultChar
NULL 非空字符 使用系统默认替代字符,必要时设置lpUsedDefaultChar
非空字符 非空字符 使用用户指出的替代字符,必要时设置lpUsedDefaultChar