将 UTF-16(宽字符)字符串映射到新字符串。新字符串不一定来自多字节字符集。
注意
错误地 使用WideCharToMultiByte函数可能会危及应用程序的安全性。调用此函数很容易导致缓冲区溢出,因为lpWideCharStr指示的输入缓冲区大小等于 Unicode 字符串中的字符数,而lpMultiByteStr指示的输出缓冲区大小等于字节数。为避免缓冲区溢出,您的应用程序必须指定适合缓冲区接收的数据类型的缓冲区大小。
从 UTF-16 转换为非 Unicode 编码的数据可能会丢失数据,因为代码页可能无法表示特定 Unicode 数据中使用的每个字符。有关更多信息,请参阅安全注意事项:国际功能。
注意 ANSI 代码页在不同的计算机上可以不同,或者可以为单个计算机更改,从而导致数据损坏。为获得最一致的结果,应用程序应使用 Unicode,例如 UTF-8 或 UTF-16,而不是特定的代码页,除非旧标准或数据格式禁止使用 Unicode。如果无法使用 Unicode,则应用程序应在协议允许的情况下使用适当的编码名称标记数据流。HTML 和 XML 文件允许标记,但文本文件不允许。句法
int WideCharToMultiByte(
[in] UINT CodePage,
[in] DWORD dwFlags,
[in] _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr,
[in] int cchWideChar,
[out, optional] LPSTR lpMultiByteStr,
[in] int cbMultiByte,
[in, optional] LPCCH lpDefaultChar,
[out, optional] LPBOOL lpUsedDefaultChar
);
参数
[in] CodePage
用于执行转换的代码页。此参数可以设置为操作系统中已安装或可用的任何代码页的值。有关代码页的列表,请参阅代码页标识符。您的应用程序还可以指定下表中显示的值之一。
[in] dwFlags
指示转换类型的标志。应用程序可以指定以下值的组合。当没有设置这些标志时,该函数执行得更快。应用程序应使用特定值 WC_DEFAULTCHAR 指定 WC_NO_BEST_FIT_CHARS 和 WC_COMPOSITECHECK 以检索所有可能的转换结果。如果未提供所有三个值,则会丢失某些结果。
价值 | 意义 | ||||||
---|---|---|---|---|---|---|---|
WC_COMPOSITECHECK |
转换复合字符,由一个基本字符和一个非空格字符组成,每个字符具有不同的字符值。将这些字符转换为预组合字符,这些字符具有用于基本非间距字符组合的单个字符值。例如,在字符 è 中,e 是基本字符,重音符号是非空格字符。
注意 Windows 通常用预先组合的数据表示 Unicode 字符串,因此不需要使用 WC_COMPOSITECHECK 标志。
您的应用程序可以将 WC_COMPOSITECHECK 与以下任一标志结合使用,默认值为 WC_SEPCHARS。当 Unicode 字符串中的基本非间距字符组合没有预组合映射可用时,这些标志确定函数的行为。如果没有提供这些标志,则该函数的行为就像设置了 WC_SEPCHARS 标志一样。有关更多信息,请参阅备注部分中的 WC_COMPOSITECHECK 和相关标志。
|
||||||
WC_ERR_INVALID_CHARS |
Windows Vista 及更高版本:如果遇到无效输入字符,则失败(通过返回 0 并将最后一个错误代码设置为 ERROR_NO_UNICODE_TRANSLATION)。您可以通过调用GetLastError来检索最后一个错误代码。如果未设置此标志,则该函数将用 U+FFFD(根据指定代码页进行适当编码)替换非法序列,并通过返回已转换字符串的长度来成功。请注意,这个标志时才适用代码页被指定为CP_UTF8或54936.它不能与其他代码页值来使用。 | ||||||
WC_NO_BEST_FIT_CHARS |
将任何未直接转换为多字节等效项的 Unicode 字符转换为lpDefaultChar指定的默认字符。换句话说,如果从 Unicode 转换为多字节并再次转换回 Unicode 不会产生相同的 Unicode 字符,则该函数使用默认字符。该标志可以单独使用或与其他定义的标志结合使用。 对于需要验证的字符串,例如文件、资源和用户名,应用程序应始终使用 WC_NO_BEST_FIT_CHARS 标志。此标志可防止函数将字符映射到看起来相似但语义非常不同的字符。在某些情况下,语义变化可能是极端的。例如,“∞”(无穷大)的符号在某些代码页中映射到 8(八)。 |
对于下面列出的代码页,dwFlags必须为 0。否则,函数将失败并显示 ERROR_INVALID_FLAGS。
- 50220
- 50221
- 50222
- 50225
- 50227
- 50229
- 57002 至 57011
- 65000 (UTF-7)
- 42(符号)
[in] lpWideCharStr
指向要转换的 Unicode 字符串的指针。
[in] cchWideChar
由lpWideCharStr指示的字符串的大小(以字符为单位)。或者,如果字符串以空字符结尾,则可以将此参数设置为 -1。如果cchWideChar设置为 0,则函数失败。
如果此参数为 -1,则该函数将处理整个输入字符串,包括终止的空字符。因此,结果字符串有一个终止空字符,函数返回的长度包括这个字符。
如果此参数设置为正整数,则该函数将准确处理指定数量的字符。如果提供的大小不包括终止空字符,则结果字符串不是以空终止的,并且返回的长度不包括该字符。
[out, optional] lpMultiByteStr
指向接收转换后字符串的缓冲区的指针。
[in] cbMultiByte
由lpMultiByteStr指示的缓冲区的大小(以字节为单位)。如果此参数设置为 0,则该函数返回lpMultiByteStr所需的缓冲区大小,并且不使用输出参数本身。
[in, optional] lpDefaultChar
如果无法在指定的代码页中表示字符,则指向要使用的字符的指针。如果函数要使用系统默认值,则应用程序将此参数设置为NULL。要获取系统默认字符,应用程序可以调用GetCPInfo或GetCPInfoEx函数。
欲了解CP_UTF7和CP_UTF8设置代码页,这个参数必须设置为NULL。否则,该函数会因 ERROR_INVALID_PARAMETER 而失败。
[out, optional] lpUsedDefaultChar
指向标志的指针,该标志指示函数是否在转换中使用了默认字符。如果源字符串中的一个或多个字符无法在指定的代码页中表示,则该标志设置为TRUE。否则,该标志设置为FALSE。此参数可以设置为NULL。
欲了解CP_UTF7和CP_UTF8设置代码页,这个参数必须设置为NULL。否则,该函数会因 ERROR_INVALID_PARAMETER 而失败。
返回值
如果成功,则返回写入lpMultiByteStr指向的缓冲区的字节数。如果函数成功并且cbMultiByte为 0,则返回值是lpMultiByteStr指示的缓冲区所需的大小(以字节为单位)。另请参阅dwFlags以获取有关在输入无效序列时 WC_ERR_INVALID_CHARS 标志如何影响返回值的信息。
如果不成功,该函数返回 0。要获取扩展错误信息,应用程序可以调用GetLastError,它可以返回以下错误代码之一:
- ERROR_INSUFFICIENT_BUFFER。提供的缓冲区大小不够大,或者错误地设置为NULL。
- ERROR_INVALID_FLAGS。为标志提供的值无效。
- ERROR_INVALID_PARAMETER。任何参数值都无效。
- ERROR_NO_UNICODE_TRANSLATION。在字符串中发现无效的 Unicode。
备注
该lpMultiByteStr和lpWideCharStr指针必须是不一样的。如果它们相同,则函数失败,GetLastError返回 ERROR_INVALID_PARAMETER。
如果在没有终止空字符的情况下显式指定输入字符串长度,则WideCharToMultiByte不会空终止输出字符串。要空终止此函数的输出字符串,应用程序应传入 -1 或显式计算输入字符串的终止空字符。
如果cbMultiByte小于cchWideChar,则此函数将cbMultiByte指定的字符数写入lpMultiByteStr指示的缓冲区。但是,如果代码页设置为CP_SYMBOL和cbMultiByte小于cchWideChar,功能没有写入字符lpMultiByteStr。
当lpDefaultChar和lpUsedDefaultChar都设置为NULL时,WideCharToMultiByte函数的运行效率最高。下表显示了这些参数的四种可能组合的函数行为。
lp默认字符 | lpUsedDefaultChar | 结果 |
---|---|---|
NULL | NULL | 没有默认检查。这些参数设置是与此功能一起使用的最有效的设置。 |
Non-null character | NULL | 使用指定的默认字符,但不设置lpUsedDefaultChar。 |
NULL | Non-null character | 使用系统默认字符并在必要时设置lpUsedDefaultChar。 |
Non-null character | Non-null character | 使用指定的默认字符并在必要时设置lpUsedDefaultChar。 |
从 Windows Vista 开始,此功能完全符合 UTF-8 和 UTF-16 的 Unicode 4.1 规范。早期操作系统上使用的函数对单独的代理半部分或不匹配的代理对进行编码或解码。在早期版本的 Windows 中编写的依赖此行为来编码随机非文本二进制数据的代码可能会遇到问题。但是,使用此函数生成有效 UTF-8 字符串的代码的行为方式与早期 Windows 操作系统上的行为方式相同。
从 Windows 8 开始:WideCharToMultiByte 在 Stringapiset.h 中声明。在 Windows 8 之前,它是在 Winnls.h 中声明的。
WC_COMPOSITECHECK 和相关标志
正如使用 Unicode 规范化来表示字符串 中所讨论的,Unicode 允许同一字符串的多种表示(从语言上解释)。例如,带有分音符号(变音符号)的大写字母 A 可以表示为单个 Unicode 代码点“Ä”(U+00C4),也可以分解为大写字母 A 和组合分音符号字符(“A”+“¨”)的组合,即 U+0041 U+0308)。但是,大多数代码页仅提供组合字符。
WC_COMPOSITECHECK 标志使WideCharToMultiByte函数测试分解的 Unicode 字符并尝试在将它们转换为请求的代码页之前组合它们。此标志仅可用于转换为单字节 (SBCS)或双字节 (DBCS)代码页(代码页 < 50000,不包括代码页 42)。如果您的应用程序需要将分解的 Unicode 数据转换为单字节或双字节代码页,此标志可能很有用。但是,并非所有字符都可以通过这种方式进行转换,以 Unicode 格式保存和存储此类数据更为可靠。
当应用程序使用 WC_COMPOSITECHECK 时,某些字符组合可能仍然不完整或可能有额外的非空格字符剩余。例如,A + ¨ + ¨ 组合成 Ä + ¨。使用 WC_DISCARDNS 标志会导致函数丢弃额外的非空格字符。使用 WC_DEFAULTCHAR 标志会导致函数使用默认替换字符(通常为“?”)。使用 WC_SEPCHARS 标志会导致函数尝试将每个额外的非空格字符转换为目标代码页。通常这个标志也会导致使用替换字符(“?”)。但是,对于代码页 1258(越南语)和 20269,存在并且可以使用非空格字符。这些代码页的转换并不完美。某些组合无法正确转换为代码页 1258,
例子
ISDSC_STATUS DiscpUnicodeToAnsiSize(
IN __in PWCHAR UnicodeString,
OUT ULONG *AnsiSizeInBytes
)
/*++
Routine Description:
This routine will return the length needed to represent the unicode
string as ANSI
Arguments:
UnicodeString is the unicode string whose ansi length is returned
*AnsiSizeInBytes is number of bytes needed to represent unicode
string as ANSI
Return Value:
ERROR_SUCCESS or error code
--*/
{
_try
{
*AnsiSizeInBytes = WideCharToMultiByte(CP_ACP,
0,
UnicodeString,
-1,
NULL,
0, NULL, NULL);
} _except(EXCEPTION_EXECUTE_HANDLER) {
return(ERROR_NOACCESS);
}
return((*AnsiSizeInBytes == 0) ? GetLastError() : ERROR_SUCCESS);
}
要求
最低支持客户端 | Windows 2000 Professional [桌面应用程序 | UWP 应用程序] |
最低支持服务器 | Windows 2000 Server [桌面应用程序 | UWP 应用程序] |
目标平台 | Windows |
头文件 | stringapiset.h(包括 Windows.h) |
Library | Kernel32.lib |
dll | Kernel32.dll |