【问题标题】:WideCharToMultiByte() vs. wcstombs()WideCharToMultiByte() 与 wcstombs()
【发布时间】:2011-08-03 00:17:26
【问题描述】:

WideCharToMultiByte() 和 wcstombs() 有什么区别 什么时候用哪个?

【问题讨论】:

    标签: c++ winapi unicode widechar wchar


    【解决方案1】:
    • WideCharToMultiByte 是一个 Windows API 函数,用于在存储在 CHAR 中的 Windows 定义的多字节代码页和存储在 WCHAR 中的 UTF16 之间进行转换。要使用的代码页作为第一个参数传递,并且可以作为 CP_ACP 传递,这意味着特定于系统当前区域设置的代码页 - 在控制面板本地化工具“用于非 Unicode 程序的语言”中设置。它由 #include 访问,并且仅在 Windows 上可用。

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

    • std::codecvt 是 C++ 标准库模板类,用于在各种编码之间转换字符串,使用各种特征类型机制来定义源编码和目标编码。

    还有其他库,包括 ICONV 或 ICU,它们也可以进行各种 unicode 多字节转换。

    【讨论】:

    • 这个问题已经有了一个选定的答案,我只是想也许有人应该提到(鉴于问题被标记为 c++,而不是 c)c++ 也有解决方案。
    【解决方案2】:

    与任何其他函数一样:使用在您的程序中执行您需要的函数。

    WideCharToMultiByte 从 UTF-16(用作 Win32 WCHAR 表示)转换为您选择的 Win32 代码页。

    wcstombs 从实现定义的内部wchar_t 表示转换为当前实现定义的内部多字节表示。

    因此,如果您的程序是使用大量使用和返回 WCHAR 字符串的 WIN32 API 函数的本机 Win32 程序,那么您需要WideCharToMultiByte。如果您编写了一些基于标准库(不是 Win32 API)的函数,这些函数使用标准 C wchar_t 字符串,那么您需要wcstombs

    【讨论】:

      【解决方案3】:

      简而言之:WideCharToMultiByte 函数在参数列表中公开了用于转换的编码/代码页,而wcstombs 没有。这是一个主要的 PITA,作为标准的does not define,将使用什么编码来生成wchar_t,而作为开发人员,您当然需要知道要转换为/从什么编码。

      除此之外,WideCharToMultiByte 当然是一个 Windows API 函数,在任何其他平台上都不可用。

      因此,如果您的应用程序不是专门为可移植到非 Windows 操作系统而编写的,那么我建议您使用WideCharToMultiByte 而无需考虑。否则,您可能想与wcstombs 搏斗,或者(最好是恕我直言)考虑使用功能齐全的可移植Unicode 库,例如ICU

      【讨论】:

      • “标准没有定义用于生成 wchar_t 的编码,而作为开发人员,您当然需要知道要转换成/从什么编码”。这取决于你追求什么。 WideCharToMultiByte 从 UTF-16 转换为您选择的 Win32 代码页。 wcstombs 从实现定义的内部wchar_t 表示转换为当前实现定义的内部多字节表示。开发人员无需了解实现定义的编码。
      • @SergeDundich:如果您只是在 C 库函数之间传递字符串,那么不需要知道使用的编码。然而,在实践中,您这样做是为了与外部实体进行互操作(例如,在最简单的情况下,对流进行读/写)。并且外部实体当然确实关心你提供给它的编码。
      • “然而,实际上,您这样做是为了与外部实体进行互操作”或者在基于 wchar_t 和基于 char 的函数输入/输出之间转换字符串。 “外部实体当然会关心你输入的编码”是的。但有时外部实体期望例如以实现定义的标准方式表示的多字节字符串(甚至可能碰巧是用户可配置的)。
      • @SergeDundich:我不同意。当没有人(包括那个实体)知道“实现定义”的含义时,外部实体怎么可能期望以“实现定义的方式”编码的字符串?
      • >这不是真的。术语“实现定义”与“未定义”不同。 “实施定义”是指由实施明确定义和记录。
      【解决方案4】:

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

      归根结底,wcstombs() 调用一个特定于系统的函数,在 Win32 上很可能直接调用 WideCharToMultiByte() - 然而,它可能会完全绕过这个函数,直接进入内部.
      无论如何,没有实际区别。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-02
          • 2011-03-23
          • 2011-01-17
          • 2011-01-12
          • 1970-01-01
          • 1970-01-01
          • 2011-06-10
          • 2016-03-06
          相关资源
          最近更新 更多