Функция WideCharToMultiByte (stringapiset.h)
Сопоставляет строку UTF-16 (расширенный символ) с новой строкой символов. Новая строка символов не обязательно из многобайтового набора символов.
Данные, преобразованные из кодировки UTF-16 в кодировки, отличной от Юникода, могут быть потеряны, так как кодовая страница может не представлять все символы, используемые в конкретных данных Юникода. Дополнительные сведения см. в разделе Вопросы безопасности: международные функции.
Синтаксис
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_NO_BEST_FIT_CHARS и WC_COMPOSITECHECK с определенным значением WC_DEFAULTCHAR, чтобы получить все возможные результаты преобразования. Если не указаны все три значения, некоторые результаты будут отсутствовать.
Значение | Значение | ||||||
---|---|---|---|---|---|---|---|
|
Преобразуйте составные символы, состоящие из базового и несмесяного символов, каждый из которых имеет разные значения символов. Перевод этих символов в предварительно композированные символы, которые имеют одно значение символа для сочетания базовых и неспеховных символов. Например, в символе è e является базовым символом, а знак подчеркивания — символом nonspacing. Примечание Windows обычно представляет строки Юникода с предварительно композированные данные, что делает использование флага WC_COMPOSITECHECK ненужным.
Приложение может сочетать WC_COMPOSITECHECK с любым из следующих флагов, а значение по умолчанию — WC_SEPCHARS. Эти флаги определяют поведение функции, когда в строке Юникода не доступно предварительно компилированного сопоставления для сочетания символов, не являющихся базовыми. Если ни один из этих флагов не указан, функция ведет себя так, как если бы установлен флаг WC_SEPCHARS. Дополнительные сведения см. в разделе WC_COMPOSITECHECK и связанных флагов в разделе Примечания .
|
||||||
|
Windows Vista и более поздних версий: Ошибка (возвращая 0 и задав код последней ошибки ERROR_NO_UNICODE_TRANSLATION), если обнаружен недопустимый входной символ. Вы можете получить код последней ошибки с помощью вызова GetLastError. Если этот флаг не задан, функция заменяет недопустимые последовательности U+FFFD (закодированные в соответствии с заданной кодовой страницой) и возвращает длину преобразованной строки. Обратите внимание, что этот флаг применяется только в том случае, если CodePage указан как CP_UTF8 или 54936. Его нельзя использовать с другими значениями кодовой страницы. | ||||||
|
Перевод любых символов Юникода, которые не преобразуют напрямую в многобайтовые эквиваленты символа по умолчанию, заданного lpDefaultChar. Иными словами, если при повторном переводе из Юникода в многобайтовый и обратно в Юникод не возвращается один и тот же символ Юникода, функция использует символ по умолчанию. Этот флаг можно использовать сам по себе или в сочетании с другими определенными флагами.
Для строк, требующих проверки, например файлов, ресурсов и имен пользователей, приложение всегда должно использовать флаг 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
Указатель на преобразуемую строку Юникода.
[in] cchWideChar
Размер строки в символах, указанной lpWideCharStr. Кроме того, этот параметр может иметь значение -1, если строка завершается null. Если параметр cchWideChar имеет значение 0, функция завершается ошибкой.
Если этот параметр имеет значение -1, функция обрабатывает всю входную строку, включая завершающий символ NULL. Таким образом, результирующая строка символов содержит завершающий символ NULL, а длина, возвращаемая функцией, включает этот символ.
Если для этого параметра задано положительное целое число, функция обрабатывает точно указанное число символов. Если указанный размер не содержит завершающий символ NULL, результирующая строка символов не заканчивается null, а возвращаемая длина не включает этот символ.
[out, optional] lpMultiByteStr
Указатель на буфер, который получает преобразованную строку.
[in] cbMultiByte
Размер буфера в байтах, указанный lpMultiByteStr. Если это значение равно 0, функция возвращает требуемый размер буфера в байтах, включая любой завершающий символ NULL, и не использует буфер lpMultiByteStr .
[in, optional] lpDefaultChar
Указатель на символ, используемый, если символ не может быть представлен на указанной кодовой странице. Приложение задает этому параметру значение NULL , если функция использует системное значение по умолчанию. Чтобы получить системный символ по умолчанию, приложение может вызвать функцию GetCPInfo или GetCPInfoEx .
Для параметров CP_UTF7 и CP_UTF8 для CodePage этот параметр должен иметь значение NULL. В противном случае функция завершается сбоем с ERROR_INVALID_PARAMETER.
[out, optional] lpUsedDefaultChar
Указатель на флаг, указывающий, использовала ли функция символ по умолчанию при преобразовании. Флаг имеет значение TRUE , если один или несколько символов в исходной строке не могут быть представлены на указанной кодовой странице. В противном случае флагу присваивается значение FALSE. Для этого параметра можно задать значение NULL.
Для параметров CP_UTF7 и CP_UTF8 для CodePage этот параметр должен иметь значение NULL. В противном случае функция завершается сбоем с ERROR_INVALID_PARAMETER.
Возвращаемое значение
В случае успешного выполнения возвращает число байтов, записанных в буфер, на который указывает lpMultiByteStr. Если функция выполняется успешно и cbMultiByte имеет значение 0, возвращаемое значение является требуемым размером в байтах для буфера, указанного lpMultiByteStr. Сведения о том, как флаг WC_ERR_INVALID_CHARS влияет на возвращаемое значение при входе недопустимых последовательностей, см. в разделе dwFlags .
Функция возвращает значение 0, если не удалось. Чтобы получить расширенные сведения об ошибке, приложение может вызвать Метод GetLastError, который может возвращать один из следующих кодов ошибок:
- ERROR_INSUFFICIENT_BUFFER. Указанный размер буфера был недостаточно велик или неправильно задано значение NULL.
- ERROR_INVALID_FLAGS. Значения, предоставленные для флагов, были недопустимыми.
- ERROR_INVALID_PARAMETER. Любое из значений параметров было недопустимым.
- ERROR_NO_UNICODE_TRANSLATION. В строке обнаружен недопустимый Юникод.
Комментарии
Указатели lpMultiByteStr и lpWideCharStr не должны совпадать. Если они совпадают, функция завершается сбоем, и GetLastError возвращает ERROR_INVALID_PARAMETER.
WideCharToMultiByte не завершает выходную строку со значением NULL, если длина входной строки явно указана без завершающего символа NULL. Чтобы завершить выходную строку для этой функции null, приложение должно передать значение -1 или явно подсчитать завершающий символ NULL для входной строки.
Если значение cbMultiByte меньше , чем cchWideChar, эта функция записывает количество символов, заданное параметром cbMultiByte, в буфер, указанный lpMultiByteStr. Однако если для CodePage задано значение CP_SYMBOL а cbMultiByte меньше , чем cchWideChar, функция не записывает символы в lpMultiByteStr.
Функция WideCharToMultiByte работает наиболее эффективно, если для lpDefaultChar и lpUsedDefaultChar задано значение NULL. В следующей таблице показано поведение функции для четырех возможных сочетаний этих параметров.
lpDefaultChar | lpUsedDefaultChar | Результат |
---|---|---|
NULL | NULL | Нет проверки по умолчанию. Эти параметры параметров являются наиболее эффективными для использования с этой функцией. |
Символ, отличный от NULL | NULL | Использует указанный символ по умолчанию, но не задает lpUsedDefaultChar. |
NULL | Символ, отличный от NULL | Использует системный символ по умолчанию и при необходимости задает lpUsedDefaultChar . |
Символ, отличный от NULL | Символ, отличный от NULL | Использует указанный символ по умолчанию и при необходимости задает lpUsedDefaultChar . |
Начиная с Windows Vista эта функция полностью соответствует спецификации Юникода 4.1 для UTF-8 и UTF-16. Функция, используемая в более ранних операционных системах, кодирует или декодирует одинокие суррогатные половины или несовпадение суррогатных пар. Код, написанный в более ранних версиях Windows, который использует такое поведение для кодирования случайных нетекстовых двоичных данных, может столкнуться с проблемами. Однако код, использующий эту функцию для создания допустимых строк UTF-8, будет вести себя так же, как и в более ранних операционных системах Windows.
Начиная с Windows 8: WideCharToMultiByte объявляется в Stringapiset.h. До Windows 8 он был объявлен в Winnls.h.
WC_COMPOSITECHECK и связанные флаги
Как описано в разделе Использование нормализации Юникода для представления строк, Юникод допускает несколько представлений одной строки (интерпретируется лингвистически). Например, прописная буква A с диерезами (umlaut) может быть представлена либо предварительно в виде одной кодовой точки Юникода "Ä" (U+00C4), либо разложена как сочетание прописной буквы A и объединяющего символа диереза ("A" + " esis", то есть U+0041 U+0308). Однако большинство кодовых страниц содержат только составные символы.Флаг WC_COMPOSITECHECK приводит к тому, что функция WideCharToMultiByte проверяет наличие разложенных символов Юникода и пытается создать их перед преобразованием в запрошенную кодовую страницу. Этот флаг доступен только для преобразования в однобайтовые (SBCS) или двухбайтовые (DBCS) кодовые страницы (кодовые страницы < 50000, за исключением кодовой страницы 42). Если приложению необходимо преобразовать разложенные данные Юникода в однобайтовые или двойные кодовые страницы, этот флаг может оказаться полезным. Однако не все символы можно преобразовать таким образом, и это более надежно для сохранения и хранения таких данных, как Юникод.
Если приложение использует WC_COMPOSITECHECK, некоторые сочетания символов могут оставаться неполными или иметь дополнительные символы, которые не содержат символов. Например, A + ирование + ирование объединяется с Ä + ированием. Использование флага WC_DISCARDNS приводит к тому, что функция отбрасывает дополнительные символы без знака. Использование флага WC_DEFAULTCHAR приводит к тому, что функция будет использовать символ замены по умолчанию (обычно "?"). Использование флага WC_SEPCHARS приводит к тому, что функция попытается преобразовать каждый дополнительный символ, не содержащий знака, в целевую кодовую страницу. Обычно этот флаг также вызывает использование символа замены ("?"). Однако для кодовой страницы 1258 (вьетнамский) и 20269 существуют и могут использоваться символы без знака. Преобразования для этих кодовых страниц не являются идеальными. Некоторые сочетания неправильно преобразуются в кодовую страницу 1258, а WC_COMPOSITECHECK повреждает данные на кодовой странице 20269. Как упоминалось ранее, надежнее спроектировать приложение для сохранения и хранения таких данных, как Юникод.
Примеры
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 Профессиональная [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows 2000 Server [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | stringapiset.h (включая Windows.h) |
Библиотека | Kernel32.lib |
DLL | Kernel32.dll |