【问题标题】:wchar_t vs char for creating an APIwchar_t vs char 用于创建 API
【发布时间】:2014-07-25 12:44:15
【问题描述】:

我正在创建一个 C++ 库,旨在用于以 Java、C#、Delphi 等不同语言编写的不同应用程序。

我时不时地陷入 wstrings、strings、char*、wchar_t* 之间的转换。例如。我坚持使用 wchar_t,但不得不使用接受 chars 其他类似问题的正则表达式库。

我希望坚持使用 w 或普通字符串。我的库将主要处理 ASCII 字符,但也可以在名称等中包含非 ASCII 字符。所以,我可以永久切换到 char 而不是 wchar_t 和 string 而不是 wstring。我可以对它们进行 unicode 支持吗?它是否会影响跨不同平台和语言的可伸缩性和可移植性。

请指教。

【问题讨论】:

  • @bames53 你能告诉我这个问题吗
  • 只使用普通字符。如果人们想使用宽字符,他们可以使用 utf8(完全支持 unicode)

标签: c winapi


【解决方案1】:

您需要决定使用哪种编码。一些注意事项:

  • 如果您可以使用非 ASCII 字符,那么选择 ASCII 或 8 位 ANSI 就没有意义了。这样会导致失望并有丢失数据的风险。

  • 选择一种编码并坚持下去是有意义的。到处。 Windows API 在支持 ANSI 和 Unicode 方面是不寻常的,但这是由于旧软件的向后兼容性。如果微软从头开始,那将只有一种编码。

  • Unicode 编码最常见的选择是 UTF-8 和 UTF-16。任何体面的环境都会支持两者。任何一种选择都可能是合理的。

  • Java、VB、C# 和 Delphi 都对 UTF-16 有很好的支持,并且它们都使用 UTF-16 作为它们的原生字符串类型(在 Delphi 的情况下,原生字符串类型是 UTF-16仅在Delphi 2009 及更高版本中。对于早期版本,您可以使用WideString 字符串类型。

  • 大多数操作系统平台本身都是 UTF-16(*Nix 系统,如 Linux,改为使用 UTF-8),因此使用 UTF-16 可能是最简单的。

  • 另一方面,UTF-8 可能是面向字节的技术上更好的选择,并且向后兼容 8 位 ASCII。很有可能,如果 Unicode 是从头开始发明的,就不会有 UTF-16,而 UTF-8 将是可变长度编码。

您已将问题表述为在charwchar_t 之间进行选择。我认为真正的选择是您首选的编码应该是什么。您还必须注意wchar_t 在某些系统上是 16 位 (UTF-16),但在其他系统上是 32 位 (UTF-32)。它不是可移植的数据类型。这就是为什么 C++11 引入了新的 char16_t 和 char32_t` 数据类型来纠正这种歧义。

【讨论】:

  • 如何设置编码。我的意思是我可以使用 char* 和 UTF-8 编码
  • 这取决于。如果您的代码在具有 16 位字符的系统上编译,那么您不能使用 char* 来保存 UTF-8 数据。但这样的系统是不寻常的。我认为使用char* 来保存UTF-8 有效负载是很常见的。但你不只是“设置编码”。您将需要大量的库支持。在 C 语言中真的没有什么好玩的,它让你在国际化的荒野中独自闲逛。甚至 C++ 也好不到哪里去。
  • 我有点困惑,我的库面向 Windows XP、Vista、7 和 8,将在 Windows 7 机器上编译。头文件中是否有任何声明以启用 utf-8 字符字符串。
  • 不,没有这么简单。如果您只针对 Windows,那么 UTF-16 会更简单。
  • @adnankamili wchar_t 并不总是 UTF-16,它也可以是 UTF-32(linux 和 mac)
【解决方案2】:

Unicode 和简单字符之间的主要区别在于代码页。只有一个char* 指针不足以理解字符串的含义。它可以是某种特定的编码,可以是多字节等。宽字符串没有这些注意事项。

在许多情况下,国际方面并不重要。在这种情况下,这两种表示之间的差异很小。您需要回答的主要问题:国际化对您的图书馆重要吗?

【讨论】:

    【解决方案3】:

    现代 Windows 编程应该倾向于使用定义 UNICODE 的构建,因此使用宽字符和宽字符 API。这对于提高性能(Windows API 层后面的转换更少或没有转换)、改进的功能(有时 ANSI 包装器不公开宽函数的所有功能)是可取的,并且通常它避免了无法表示字符的问题不在系统的当前代码页上(因此实际上无法表示非 ASCII 字符)。

    当您必须与不使用宽字符的事物交互时,这可能会很困难。例如,虽然 Windows API 具有宽字符文件名,但 Linux 文件系统通常使用字节串。虽然按照惯例,这些字节串通常是 UTF-8,但几乎没有强制执行。如果所讨论的语言在 API 级别不理解宽字符,则与其他语言的交互也可能很困难。理想情况下,此类语言选择了特定的编码,例如 UTF-8,允许您在边界处与该编码进行转换。

    这是一项一般性建议:在内部使用 Unicode 进行所有处理,并在边界处根据需要进行转换。如果您对此还不熟悉,最好参考Joel's article on Unicode

    【讨论】:

      猜你喜欢
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多