Функция WideCharToMultiByte (stringapiset.h)

Сопоставляет строку UTF-16 (расширенный символ) с новой строкой символов. Новая строка символов не обязательно из многобайтового набора символов.

Осторожностью Неправильное использование функции WideCharToMultiByte может поставить под угрозу безопасность приложения. Вызов этой функции может легко вызвать переполнение буфера, так как размер входного буфера, указанного lpWideCharStr , равен количеству символов в строке Юникода, а размер выходного буфера, указанного lpMultiByteStr , равен количеству байтов. Чтобы избежать переполнения буфера, приложение должно указать размер буфера, соответствующий типу данных, который получает буфер.

Данные, преобразованные из кодировки UTF-16 в кодировки, отличной от Юникода, могут быть потеряны, так как кодовая страница может не представлять все символы, используемые в конкретных данных Юникода. Дополнительные сведения см. в разделе Вопросы безопасности: международные функции.

 
Примечание Кодовые страницы ANSI могут быть разными на разных компьютерах или изменяться для одного компьютера, что приводит к повреждению данных. Для получения наиболее согласованных результатов приложения должны использовать Юникод, например UTF-8 или UTF-16, вместо определенной кодовой страницы, если только устаревшие стандарты или форматы данных не препятствуют использованию Юникода. Если использование Юникода невозможно, приложения должны помечать поток данных соответствующим именем кодирования, если это разрешено протоколами. 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

Кодовая страница, используемая при преобразовании. Для этого параметра можно задать значение любой кодовой страницы, установленной или доступной в операционной системе. Список кодовых страниц см. в разделе Кодовые страницы Идентификаторы. Приложение также может указать одно из значений, показанных в следующей таблице.

Значение Значение
CP_ACP
Системная кодовая страница Windows ANSI по умолчанию.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_MACCP
Текущая системная кодовая страница Macintosh.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
Примечание Это значение используется в основном в устаревшем коде и, как правило, не требуется, так как современные компьютеры Macintosh используют Юникод для кодирования.
 
CP_OEMCP
Текущая страница кода изготовителя оборудования системы.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_SYMBOL
Windows 2000: Кодовая страница символов (42).
CP_THREAD_ACP
Windows 2000: Кодовая страница Windows ANSI для текущего потока.
Примечание Это значение может отличаться на разных компьютерах, даже в одной сети. Его можно изменить на том же компьютере, что приведет к непоправимому повреждению хранимых данных. Это значение предназначено только для временного использования, а постоянное хранилище должно использовать UTF-16 или UTF-8, если это возможно.
 
CP_UTF7
UTF-7. Используйте это значение только при принудительном использовании 7-разрядного транспортного механизма. Рекомендуется использовать UTF-8. Если задано это значение, lpDefaultChar и lpUsedDefaultChar должны иметь значение NULL.
CP_UTF8
UTF-8. Если задано это значение, lpDefaultChar и lpUsedDefaultChar должны иметь значение NULL.

[in] dwFlags

Флаги, указывающие тип преобразования. Приложение может указать сочетание следующих значений. Функция выполняется быстрее, если ни один из этих флагов не задан. Приложение должно указать WC_NO_BEST_FIT_CHARS и WC_COMPOSITECHECK с определенным значением WC_DEFAULTCHAR, чтобы получить все возможные результаты преобразования. Если не указаны все три значения, некоторые результаты будут отсутствовать.

Значение Значение
WC_COMPOSITECHECK
Преобразуйте составные символы, состоящие из базового и несмесяного символов, каждый из которых имеет разные значения символов. Перевод этих символов в предварительно композированные символы, которые имеют одно значение символа для сочетания базовых и неспеховных символов. Например, в символе è e является базовым символом, а знак подчеркивания — символом nonspacing.
Примечание Windows обычно представляет строки Юникода с предварительно композированные данные, что делает использование флага WC_COMPOSITECHECK ненужным.
 

Приложение может сочетать WC_COMPOSITECHECK с любым из следующих флагов, а значение по умолчанию — WC_SEPCHARS. Эти флаги определяют поведение функции, когда в строке Юникода не доступно предварительно компилированного сопоставления для сочетания символов, не являющихся базовыми. Если ни один из этих флагов не указан, функция ведет себя так, как если бы установлен флаг WC_SEPCHARS. Дополнительные сведения см. в разделе WC_COMPOSITECHECK и связанных флагов в разделе Примечания .

WC_DEFAULTCHAR Замените исключения символом по умолчанию во время преобразования.
WC_DISCARDNS Во время преобразования отменяйте несмесивные символы.
WC_SEPCHARS По умолчанию. Создание отдельных символов во время преобразования.
 
WC_ERR_INVALID_CHARS
Windows Vista и более поздних версий: Ошибка (возвращая 0 и задав код последней ошибки ERROR_NO_UNICODE_TRANSLATION), если обнаружен недопустимый входной символ. Вы можете получить код последней ошибки с помощью вызова GetLastError. Если этот флаг не задан, функция заменяет недопустимые последовательности U+FFFD (закодированные в соответствии с заданной кодовой страницой) и возвращает длину преобразованной строки. Обратите внимание, что этот флаг применяется только в том случае, если CodePage указан как CP_UTF8 или 54936. Его нельзя использовать с другими значениями кодовой страницы.
WC_NO_BEST_FIT_CHARS
Перевод любых символов Юникода, которые не преобразуют напрямую в многобайтовые эквиваленты символа по умолчанию, заданного lpDefaultChar. Иными словами, если при повторном переводе из Юникода в многобайтовый и обратно в Юникод не возвращается один и тот же символ Юникода, функция использует символ по умолчанию. Этот флаг можно использовать сам по себе или в сочетании с другими определенными флагами.

Для строк, требующих проверки, например файлов, ресурсов и имен пользователей, приложение всегда должно использовать флаг WC_NO_BEST_FIT_CHARS. Этот флаг не позволяет функции сопоставлять символы с символами, которые кажутся похожими, но имеют очень разную семантику. В некоторых случаях семантические изменения могут быть экстремальными. Например, символ "∞" (бесконечность) сопоставляется с 8 (восемь) на некоторых кодовой странице.

 

Для кодовых страниц, перечисленных ниже, dwFlags должен иметь значение 0. В противном случае функция завершается сбоем с ERROR_INVALID_FLAGS.

  • 50220
  • 50221
  • 50222
  • 50225
  • 50227
  • 50229
  • От 57002 до 57011
  • 65000 (UTF-7)
  • 42 (символ)
Примечание Для кодовой страницы 65001 (UTF-8) или кодовой страницы 54936 (GB18030, Windows Vista и более поздних версий) для dwFlags необходимо задать значение 0 или WC_ERR_INVALID_CHARS. В противном случае функция завершается сбоем с ERROR_INVALID_FLAGS.
 

[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

См. также

MultiByteToWideChar

Функции Юникода и кодировки

Юникод и наборы символов

API-интерфейсы Vertdll, доступные в анклавах VBS