【问题标题】:compelling wchar_t to be 4 bytes强制 wchar_t 为 4 个字节
【发布时间】:2014-01-16 18:41:40
【问题描述】:

实际问题 - 我正在开发一个在 2 个独立硬件平台上运行的小应用程序。

编译方法及其配置由我定义和控制。

我的应用收到一个 UTF-8/ISO-8859 文本,并且应该对字符串执行一些基本操作(复制、搜索等)。

问题是,一个编译器是 GCC (sizeof(wchar_t) == 4),另一个是 Mingw(sizeof(wchar_t) == 2)。

为了支持所有 UTF-8 的可能性,我在我的代码中考虑将 wchar_t 中的“typedef”设为 uint32_t 类型,这样会强制 Mingw 编译器位于同一行,并覆盖所有 UTF- 8 个选项。

然后我打算使用标准库(mbstowcs、wcscmp、wcscpy、ex..)提供的宽字符操作函数

问题是,是否会“强制”编译器使用更多空间,可能会对库功能产生一些不良影响(除了性能之外)(更改后 mbtowcs 甚至可以在这里工作吗?)

我尝试使用 ICU,但它是一个非常大的库,因此破坏了交易。我需要它小巧可靠。

谢谢

【问题讨论】:

  • 那行不通。这不是编译器的事情,而是平台的事情。请记住,mingw 是 gcc。在 Windows 上 wchar_t 是 2 个字节。故事结局。如果您需要使用 UTF-32 数据,请使用适当大小的元素类型。然后你谈论 UTF-8。我认为你需要备份。
  • @APerson:UTF-16 也支持每个字符,但是单个wchar_t 不能代表每个代码点。
  • @A: UTF-16确实支持每一个 Unicode 字符。不过,有些字符需要代理对。您可能正在考虑 UCS-2。
  • @APerson:您正在考虑 UCS-2。 UTF-16 支持从 U+0000 到 U+10FFFF 的所有 Unicode 字符。没有其他字符。
  • @APerson:代码点 U+24B62 以 UTF-16 编码为 D852 DF62。 UCS-2 和 UTF-16 不同,UTF-16 可以表示所有 Unicode 码位。

标签: c utf-8 utf wchar-t


【解决方案1】:

以下是字符串操作的选项:

  1. 使用unsigned char(或char)和UTF-8。所有常规字符串操作函数都可以工作(如strlen()、strstr()、snprintf() 等)。

  2. 使用wchar_t 并在不同平台上使用不同的编码(Win32 使用 UTF-16,OS X 和 Linux 使用 UTF-32)。这是一条疯狂的道路,因为您必须在同一代码库中支持两种不同的编码。

  3. 使用 UTF-32 或 UTF-16 以及您自己的字符串操作函数。这是很多工作,但它是可移植的。

  4. 使用 ICU 和 UTF-16。

在大多数情况下,以 UTF-8 处理字符串非常有效。这取决于你的程序做什么。如果你正在做解析和模板之类的事情,UTF-8 很容易使用。如果您需要更复杂的功能,例如遍历断点或查找字素簇边界,那么您将需要像 Glib(使用 UTF-8)或 ICU(使用 UTF-16)这样的库。

关于索引的说明

您可能习惯于使用字符/代码点索引来索引字符串。习惯于使用代码单元索引来索引字符串:所以strlen() 返回字节数,而不是字符数。但是,实际上很少需要这样做按字符位置索引字符串。

【讨论】:

  • 因此,如果我有一个 wchar_t 字符串并且我想从索引 100 擦除到索引 105,我必须遍历数组,因为任何编码字符可能是 8 位或 16 位?还是 wchar_t 的一个元素保证(预期)只包含一个字符?
  • 我读了很多书(以前从不处理 unicode),如果我是正确的,wchat_t 在 Windows 上是 16 位,在一个元素中只包含一个字符。在 linux 上它是 32 位的,一个元素仍然只能包含一个字符。这就是utf-16、utf-32的重点吗?
  • @2501: 你读错了。在 Windows 上,wchar_t 将保存一个字符或半个字符,因为有时字符会分布在两个相邻的 wchar_t 上。这就是为什么wchar_t 毫无价值,应该避免使用,除非在进行 Windows API 调用时。
猜你喜欢
  • 2015-02-24
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 2011-09-16
相关资源
最近更新 更多