WideCharToMultiByte() против wcstombs()

В чем разница между WideCharToMultiByte() и wcstombs() Когда какой из них использовать?


person Greenhorn    schedule 11.04.2011    source источник


Ответы (5)


Вкратце: функция WideCharToMultiByte показывает кодировки/кодовые страницы, используемые для преобразования, в списке параметров, а функция wcstombs — нет. Это основная PITA, поскольку стандарт не определяет, какую кодировку следует использовать для создания wchar_t , а вам как разработчику обязательно нужно знать, в какую кодировку вы конвертируете.

Кроме того, WideCharToMultiByte, конечно же, является функцией Windows API и недоступна ни на одной другой платформе.

Поэтому я бы предложил использовать WideCharToMultiByte без раздумий, если ваше приложение специально не написано для переноса на операционные системы, отличные от Windows. В противном случае вы можете побороться с wcstombs или (предпочтительно ИМХО) изучить возможность использования полнофункциональной переносимой библиотеки Unicode, такой как ОИТ.

person Jon    schedule 11.04.2011
comment
стандарт не определяет, какая кодировка должна использоваться для создания wchar_t, в то время как вам, как разработчику, обязательно нужно знать, в какую кодировку вы конвертируете или из какой. Это зависит от того, что вы после. WideCharToMultiByte конвертирует из UTF-16 в кодовую страницу Win32 по вашему выбору. wcstombs преобразует внутреннее представление wchar_t, определенное реализацией, в текущее внутреннее многобайтовое представление, определенное реализацией. Разработчику не обязательно знать кодировки, определяемые реализацией. - person Serge Dundich; 11.04.2011
comment
@SergeDundich: если вы просто передаете строки между библиотечными функциями C, то нет, нет необходимости знать используемые кодировки. Однако на практике вы делаете это для взаимодействия с внешними объектами (например, в простейшем случае чтение/запись в потоке). И внешний объект, безусловно, действительно заботится о том, какую кодировку вы ему передаете. - person Jon; 11.04.2011
comment
На практике, однако, вы делаете это для взаимодействия с внешними объектами или для преобразования строк между функциями ввода/вывода на основе wchar_t и char. внешнему объекту, безусловно, не все равно, какую кодировку вы ему подаете True. Но иногда внешний объект ожидает, например. многобайтовая строка, представленная в реализации, определенной стандартным способом (которая может даже быть настраиваемой пользователем). - person Serge Dundich; 11.04.2011
comment
@SergeDundich: прошу не согласиться. Как внешний объект может ожидать строку, закодированную способом, определяемым реализацией, когда никто (включая этот объект) не знает, что означает определение, определяемое реализацией? - person Jon; 11.04.2011
comment
‹‹никто (включая этот объект) не знает, что означает определение реализации›› Это неправда. Термин «определенная реализация» не то же самое, что «неопределенный». Определенный реализацией означает четко определенный и документированный реализацией. - person Serge Dundich; 12.04.2011

  • WideCharToMultiByte — это функция Windows API, которая выполняет преобразование между определенными Windows многобайтовыми кодовыми страницами, хранящимися в CHAR, и UTF16, хранящимися в WCHAR. Используемая кодовая страница передается в качестве первого параметра и может быть передана как CP_ACP, что означает кодовую страницу, специфичную для текущей локали системы, установленную в инструменте локализации панели управления «Язык для использования для программ, отличных от Unicode». Доступ к нему осуществляется с помощью #include и доступен только в Windows.

  • wcstombs — это стандартная функция среды выполнения C, которая выполняет преобразование между текущей кодировкой char* среды выполнения c и кодировкой wchar_t*. setlocale iirc можно использовать для установки используемой кодовой страницы.

  • std::codecvt — это класс шаблона стандартной библиотеки C++ в , используемый для преобразования строк между различными кодировками с использованием различных механизмов типов свойств для определения исходной и конечной кодировок.

Существуют и другие библиотеки, в том числе ICONV или ICU, которые также выполняют различные преобразования юникода ‹-> многобайтовые.

person Chris Becke    schedule 11.04.2011
comment
у вопроса уже был выбранный ответ, я просто подумал, что кто-то, возможно, должен упомянуть (учитывая, что вопрос был помечен как c++, а не c), что у c++ также есть решение. - person Chris Becke; 11.04.2011

Как и с любой другой функцией: используйте функцию, которая делает то, что вам нужно в вашей программе.

WideCharToMultiByte преобразует UTF-16 (используется как представление Win32 WCHAR) в кодовую страницу Win32 по вашему выбору.

wcstombs преобразует внутреннее представление wchar_t, определенное реализацией, в текущее внутреннее многобайтовое представление, определенное реализацией.

Поэтому, если ваша программа является собственной программой Win32, которая использует множество функций WIN32 API, которые используют и возвращают строки WCHAR, вам нужно WideCharToMultiByte. Если вы пишете некоторые функции на основе стандартной библиотеки (не Win32 API), которые работают со стандартными строками C wchar_t, вам потребуется wcstombs.

person Serge Dundich    schedule 11.04.2011

Основное отличие состоит в том, что wcstombs — это стандартная функция, поэтому используйте ее, если код должен работать на любой платформе, отличной от Windows.

person Fred Foo    schedule 11.04.2011

wcstombs() является переносимым, тогда как функция WideCharToMultiByte() доступна только для win32.

Когда дело доходит до этого, wcstombs() вызывает специфичную для системы функцию, которая в Win32, скорее всего, будет прямым вызовом WideCharToMultiByte(), однако она может полностью обойти эту функцию и перейти прямо к внутренностям.
В любом случае , нет никакой практической разницы.

person Ben Stott    schedule 11.04.2011