WideCharToMultiByte() 和 wcstombs() 比较

19

WideCharToMultiByte() 和 wcstombs() 有什么不同?何时使用哪个?

5个回答

23
简而言之,WideCharToMultiByte函数在参数列表中公开了用于转换的编码/代码页,而wcstombs则没有。这是一个很大的烦恼,因为标准没有定义用于生成的编码,而作为开发人员,您肯定需要知道您正在进行的编码转换。

除此之外,WideCharToMultiByte当然是Windows API函数,在其他任何平台上都不可用。
因此,如果您的应用程序不是专门编写为可移植到非Windows操作系统,则建议毫不犹豫地使用WideCharToMultiByte。否则,您可能需要尝试使用wcstombs或(我认为最好)研究使用完整功能的便携式Unicode库,如ICU

2
标准并没有定义要使用哪种编码来生成wchar_t,但作为开发人员,您肯定需要知道您正在进行的编码转换。这取决于您想要什么。WideCharToMultiByte将从UTF-16转换为您选择的Win32代码页。wcstombs将从实现定义的内部wchar_t表示转换为当前实现定义的内部多字节表示。开发人员不必知道实现定义的编码。 - Serge Dundich
1
@SergeDundich:如果你只是在C库函数之间传递字符串,那么不需要知道所使用的编码方式。然而,在实践中,你需要这样做来与外部实体进行交互(例如,在最简单的情况下,在流上进行读/写操作)。而且,外部实体肯定会关心你提供的编码方式。 - Jon
然而在实践中,你这样做是为了与外部实体进行互操作,或者在wchar_t和char函数的输入/输出之间转换字符串。外部实体确实关心你提供的编码方式。但有时,外部实体期望例如以实现定义的标准方式表示的多字节字符串(甚至可能是用户可配置的)。 - Serge Dundich
@SergeDundich:我不同意。当没有人(包括该实体)知道“实现定义”的含义时,外部实体如何期望以“实现定义的方式”编码的字符串呢? - Jon
3
“没有人(包括该实体)知道“implementation-defined”的含义”这句话不正确。术语“implementation-defined”并非与“undefined”相同。 “Implementation-defined”表示由实现清晰定义和记录。 - Serge Dundich

13
  • WideCharToMultiByte是一个Windows API函数,用于在CHAR中转换存储的Windows定义的多字节代码页和WCHAR中存储的UTF16之间的编码。要使用的代码页作为第一个参数传递,可以传递CP_ACP,表示系统当前区域设置中设置的针对代码页的特定代码页 - 在控制面板本地化工具“用于非Unicode程序的语言”中设置。它通过#include访问,并且仅在Windows上可用。

  • wcstombs是标准C运行时函数,用于在当前char *编码和wchar_t *编码之间进行转换。setlocale(我记得)可用于设置要使用的代码页。

  • std :: codecvt是C ++标准库模板类,在codecvt中使用,用于使用各种特性类型机制在不同编码之间转换字符串。

还有其他库,包括ICONV或ICU,也可以进行各种Unicode<->多字节转换。


2
这个问题已经有了一个被选中的答案,我只是认为有人应该提到(鉴于这个问题被标记为C++而不是C),C++也有解决方案。 - Chris Becke

3
与任何其他函数一样:在程序中使用完成你所需功能的函数。 WideCharToMultiByte 将UTF-16(作为Win32 WCHAR表示)转换为您选择的Win32代码页。 wcstombs 将实现定义的内部 wchar_t 表示转换为当前实现定义的内部多字节表示。
因此,如果您的程序是本地 Win32 程序,使用大量使用和返回 WCHAR 字符串的 WIN32 API 函数,则需要使用 WideCharToMultiByte。如果您编写了基于标准库(而不是 Win32 API)的某些函数,这些函数使用标准 C wchar_t 字符串,则需要使用 wcstombs

2
主要区别在于,wcstombs是一个标准函数,因此如果代码需要在除Windows以外的任何平台上运行,请使用该函数。

2

wcstombs() 是可移植的,而 WideCharToMultiByte() 函数仅适用于 win32。

实际上,wcstombs() 调用一个特定于系统的函数,在 Win32 上很可能是一个直接调用 WideCharToMultiByte() 的函数- 不过,它也可能完全绕过该函数并直接进入内部。
无论如何,没有实际区别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接