1

这是家庭作业。我不是在寻找代码只是讨论,关于如何进行的高级建议。

我目前正在处理一项任务,我们将文件中的 UTF-16 字符转换为输出文件中的 UTF-32,反之亦然。作业说,第一步是处理仅包含小于 10 位字符的文件,但我很难过。这是我们的第一个任务,虽然我使用过 C++,但从未真正使用过 C。

我一直在阅读有关此类转换的 RFC (S.2.1),我觉得我非常了解它。我知道 UTF-32 字符实际上是 10 位,前面是 6 位定义它的组成(我相信 110110 表示第一对 16 位,110111 表示第二对“32”)。UTF-16 字符是否以 6 个前导 0 开头?

还是 UTF-16 字符小于 10 位,一旦你遇到 10 位字符,你就知道你遇到了 UTF-32 位字符?

我想我真正的问题是当它可以是 8、16 等时,“10 位字符”是什么意思。但是对我提到的任何内容的任何见解都会很棒!

4

1 回答 1

1

该作业措辞不当且具有误导性。

Unicode 定义的代码点值最多可占用20 位(U+0000 到 U+10FFFF)。所有 UTF 编码(UTF-8UTF-16UTF-32)都支持所有 20 位,只是方式不同。

UTF-8 和 UTF-16 是可变长度编码。编码给定代码点所需的字节数取决于实际代码点值。UTF-8 使用 1、2、3 或 4 个 8 位代码单元。UTF-16 使用 1 个或 2 个 16 位代码单元。

UTF-32 是一种定长编码。它总是使用 1 个 32 位代码单元,因为大多数系统没有 20 位数据类型。

实现 UTF 转换非常容易(它们被设计为可互换),但您首先需要知道源文件实际使用的是哪种编码。如果文件以 UTF-16 BOM开头 ,则很容易检测到。但是,如果不存在 BOM,则您需要询问用户编码,或者使用数据的启发式分析来尝试动态检测编码。

一旦你知道了编码,剩下的就很简单了:

  1. 如果是 UTF-16,则以 16 位块(一次 1 个代码单元)读取文件,根据需要组合相邻的 UTF-16 代理代码单元(非常容易检测)。对于每个完整的序列,提取编码的 16/20 位并以单个 UTF-32 代码单元输出它们。

  2. 如果是 UTF-32,则以 32 位块(一次 1 个代码单元)读取文件,提取 20 位,并根据需要将它们作为 1 个或 2 个 UTF-16 代码单元输出。

作业中最困难的部分是确定源文件的编码。

于 2013-09-06T15:56:17.780 回答