【问题标题】:In C++ when to use WCHAR and when to use CHAR在 C++ 中何时使用 WCHAR 以及何时使用 CHAR
【发布时间】:2014-04-17 15:08:33
【问题描述】:

我有一个问题:

一些库使用 WCHAR 作为文本参数,而其他库使用 CHAR(作为 UTF-8):我需要知道在编写自己的库时何时使用 WCHAR 或 CHAR。

【问题讨论】:

  • WCHAR 代表宽字符,通常在处理文本AFAIK的UNICODE编码样式时使用
  • C++ 中没有WCHAR。您是指 Windows 标头定义的 WCHAR 宏吗?
  • @DavidHeffernan:我以为他的意思是 Win32 标头的 WCHAR(事实上,我正在考虑编辑 OP 的标签添加 [winapi] :)
  • WCHAR 并不总是 Unicode - 它可能是 DBCS,尤其是在处理 Shift-JIS 和 BIG5 等字符集时。

标签: c++ unicode


【解决方案1】:

使用 char 并将其视为 UTF-8。这有很多原因;这个网站比我能总结得更好:

http://utf8everywhere.org/

它建议在您从任何库收到它时立即从 wchar_t 转换为 char(UTF-16 到 UTF-8),并在需要将字符串传递给它时转换回来。因此,要回答您的问题,请始终使用 char,除非 API 要求您传递或接收 wchar_t

【讨论】:

  • 实际上,它说“如果应用程序不应该专门处理文本”,则使用 UTF-8。我几乎在所有地方都倾向于使用 UTF-8,但我不确定它是否适合在编辑器中使用。例如,如果您使用 UTF-8,正则表达式之类的东西会明显变慢。
  • 好点;你是对的。听起来这不会对 OP 产生影响,但值得一提。
  • @BenHymers 你是想说 UTF-8 需要 8 位来编码任何 UNICODE 代码点吗?例如,代码点范围,U+10000-U+10FFFF,UTF-8 表示,编码一个代码点需要 4 个字节。我不知道含义,当您说时,将char 视为UTF-8。 char如何存储UTF-8编码?
  • @overexchange 不,我绝对不是这样说,我认为没有人会接受这样的答案 :) 我们谈论的是字符串而不是单个字符 - 所以是 @987654330 的数组@ 而不是单个 char - 为简洁起见,我只是省略了 'array of',因为它在此上下文中是隐含的。每个char 是UTF-8 符号的一个字节,可能是一个字节或更多。
  • @overexchange 您是否在问char 的数组是什么样的?它可以像char* 一样简单。我不认为这就是你真正的意思,因为任何引用代码点范围的人肯定都知道数组是什么;)你能更具体一点吗?
【解决方案2】:

WCHAR(或 Visual C++ 编译器上的 wchar_t)用于 Unicode UTF-16 字符串。
这是 Win32 API 使用的“本机”字符串编码。

CHAR(或char)可用于其他几种字符串格式:ANSI、MBCS、UTF-8。

由于 UTF-16 是 Win32 API 的 本机 编码,您可能希望在 Win32 API 中使用 WCHAR(以及更好的基于它的适当字符串类,例如 std::wstring)边界,在您的应用内。

而且您可以使用 UTF-8(例如,CHAR/charstd::string)在应用程序边界之外交换 Unicode 文本。例如: UTF-8 在 Internet 上被广泛使用,当你在不同平台之间交换 UTF-8 文本时,你不存在字节顺序的问题(而使用 UTF-16 你必须同时考虑 UTF-16BE big-endian 和 UTF-16LE little-endian 情况)。

您可以使用 WideCharToMultiByte()MultiByteToWideChar() Win32 API 在 UTF-16 和 UTF-8 之间进行转换。这些是纯 C API,它们可以方便地包装在 C++ 代码中,使用字符串类而不是原始字符指针,使用异常而不是原始错误代码。您可以找到here 的示例。

【讨论】:

  • @Mgetz:我知道。事实上,我认为 OP 的意思是 Win32 SDK 标头中定义的 WCHAR,而他的问题是关于 Win32 环境。请注意,我写的是:"WCHAR(或wchar_t在 Visual C++ 编译器上)"
  • 其实wchar_t根本不存储任何编码信息。它是一种总是比 char 更宽的类型(每个字的字节数更多)。
  • @Mr.C64 这似乎是一个常见的假设,我不会做出这个假设,因为 OP 没有指定编译器。
  • 你确定它在 windows 中是 UTF-16 而不是 UCS-2 吗?
  • @BrunoFerreira 实际上wchar_t 不一定比char 宽。唯一的要求是wchar_t 足够大,以便为实现支持的最大字符集的每个成员存储唯一值。因此,如果实现的最大字符集小于 256,则 wchar_t 可以是 8 位。
【解决方案3】:

正确的问题不是使用哪种类型,而是您与图书馆用户之间的合同应该是什么。 char 和 wchar_t 都可以表示不止一件事。

对我来说,正确的答案是使用 char 并考虑所有 utf-8 编码的内容,正如 utf8everywhere.org 所建议的那样。这也将使编写跨平台库变得更加容易。

请确保正确使用字符串。某些 API(如 fopen())在 Windows 上编译时会接受 char* 字符串并以不同方式处理(而不是 UTF-8)。如果 Unicode 对您很重要(并且在您处理字符串时可能很重要),请务必正确处理您的字符串。在 boost::locale 中可以看到一个很好的例子。我还建议在 Windows 上使用 boost::nowide 以在库中正确处理字符串。

【讨论】:

    【解决方案4】:

    在 Windows 中,我们坚持使用 WCHARS。标准::wstring。主要是因为如果你不这样做,你最终不得不转换,因为调用 Windows 函数。

    我有一种感觉,仅仅因为http://utf8everywhere.org/ 而在内部尝试使用 utf8 会在以后给我们带来麻烦。

    【讨论】:

      【解决方案5】:

      最好在开发 Windows 应用程序时使用 TCHAR。 TCHARs 的好处是它们可以是常规字符或 wchars,这取决于是否设置了 unicode 设置。使用 TCHAR 后,请确保您使用的所有字符串操作也以 _t 前缀开头(例如,_tcslen 表示字符串长度)。这样您就知道您的代码可以在 Unicode 和 ASCII 环境中工作。

      【讨论】:

      • TCHAR 以及在charwchar_t 之间切换的能力对于将遗留程序从遗留编码的char 迁移到wchar_t 非常有用。 TCHAR 不得用于任何其他目的。不应使用 TCHAR 编写新软件:新的 Windows 代码应明确使用(UTF-8 编码)charwchar_t
      • TCHAR 的真正坏处在于它可以是charwchar_t,因为您必须根据您使用的代码编写截然不同的代码。无论您选择什么(坦率地说,除非您正在处理文本,否则应该是 char),使用它,而不是 TCHAR
      • @armanali 哪种编码格式?您必须处理收到的任何编码格式。如果是 UTF-8,那么你编写处理 UTF-8 的代码;它是 UTF-16(BE 或 LE),然后您编写处理 UTF-16 的代码;如果是 UTF-32(BE 或 LE),那么您编写处理 UTF-32 的代码。
      • 我会说在库中使用设置敏感类型(如 TCHAR,它依赖于 UNICODE 定义)是非常糟糕的。问题是关于图书馆的。同意 utf8everywhere.org。
      猜你喜欢
      • 2011-12-15
      • 1970-01-01
      • 2012-02-20
      • 2012-06-07
      • 1970-01-01
      • 2011-10-10
      • 2015-12-17
      • 2011-07-01
      • 2016-06-06
      相关资源
      最近更新 更多