【问题标题】:Unicode, UTF-8, UTF-16 and UTF-32 questions [closed]Unicode、UTF-8、UTF-16 和 UTF-32 问题 [关闭]
【发布时间】:2014-08-21 04:43:36
【问题描述】:

我阅读了很多关于 Unicode、ASCII、代码页、所有历史、UTF-8、UTF-16 (UCS-2)、UTF-32 (UCS-4) 的发明以及使用它们的人等等,但我仍然有一些问题,我几乎找不到答案,但我无法找到答案,希望您能帮助我。

1 - Unicode 是编码字符的标准,它们为每个字符指定一个代码点。像 U+0000 (示例)。想象一下,我有一个包含这些代码点 (\u0000) 的文件,我将在应用程序的哪个点使用它?

这可能是一个愚蠢的问题,但我真的不知道我将在应用程序的哪一点使用它。 我正在创建一个应用程序,它可以使用转义符\u 读取具有这些代码点的文件,并且我知道我可以读取、解码它,但现在是下一个问题。

2 - 我需要将其转换为哪个字符集(代码页)?我看到一些 C++ 库,它们使用名称 utf8_to_unicodeutf8-to-utf16,也只有 utf8_decode,这让我感到困惑。

我不知道会不会出现这样的答案,但是有人可能会说:你需要把它转换成你要使用的代码页,但是如果我的应用程序需要国际化呢?

3 - 我想知道,在 C++ 中,如果我尝试在终端上显示非 ASCII 字符,我会得到一些令人困惑的单词。问题是:字体是什么让要显示的字符?

#include <iostream>

int main()
{
    std::cout << "ö" << std::endl;

    return 0;
}

输出(Windows):

├Â

4 - 编码进入该过程的哪个部分?它编码,获取代码点并尝试在字体上找到相等的单词?

5 = WebKit 是用于在 Web 浏览器中呈现网页的引擎,如果您将字符集指定为 UTF-8,它可以很好地处理所有字符,但如果我指定另一个字符集,它不会,不会不管我使用什么字体,会发生什么?

<html>
<head>
    <meta charset="iso-8859-1"> 
</head>
<body>
    <p>ö</p>
</body>
</html>

输出:

ö

使用:

<meta charset="utf-8">

6 - 想象一下,现在我读取了文件,对它进行了编码,我拥有了所有的代码点,我需要再次保存文件。我需要将其编码保存(\u0000)还是需要先解码以再次转换为字符然后保存?

7 - 为什么“unicode”这个词有点重载,有时被理解为 utf-16? (source)

暂时就这些了。提前致谢。

【问题讨论】:

  • characters are ambiguous: 它通常用于代码单元,但正确地指代代码点甚至字素。在这里使用一个不那么模棱两可的术语。
  • 看起来你想要一个完整的 Unicode 入门。你读过维基百科页面吗?
  • 是的,我做到了,我有这些问题。
  • 相关阅读(如果不是全部,也应该回答第7点):utf8everywhere.org
  • 谢谢@Deduplicator,我要读了。

标签: c++ unicode utf-8 utf-16 utf-32


【解决方案1】:

我正在创建一个应用程序,它可以使用转义符 \u 读取具有这些代码点的文件,并且我知道我可以读取它、解码它,但现在是下一个问题。

如果您正在编写一个处理某种自定义转义的程序,例如\uXXXX,那么何时将这些转义转换为 Unicode 代码点完全取决于您。

我需要将它转换成哪个字符集(代码页)?

这取决于你想做什么。如果您正在使用需要特定代码页的其他库,那么您可以将数据从一种编码转换为该库所需的编码。如果您没有此类第三方库强加的任何硬性要求,则可能没有理由进行任何转换。

我想知道,在 C++ 中,如果我尝试在终端上显示非 ASCII 字符,我会得到一些令人困惑的单词。

这是因为技术堆栈的各个层使用不同的编码。从您提供的示例输出中,"├Â" 我可以看到正在发生的事情是您的编译器将字符串文字编码为 UTF-8,但控制台使用的是 Windows 代码页 850。通常,当控制台出现编码问题时,您可以通过将控制台输出代码页设置为正确的值来修复它们,不幸的是,通过std::cout 传递 UTF-8 目前有一些独特的问题。在 VS2012 中使用 printf 代替对我有用:

#include <cstdio>
#include <Windows.h>

int main() {
    SetConsoleOutputCP(CP_UTF8);
    std::printf("%s\n", "ö");
}

如果 Microsoft 尚未在 VS 14 中修复 C++ 库,那么希望他们这样做。

编码进入该过程的哪个部分?它编码,获取代码点并尝试在字体上找到相等的单词?

除非您知道编码,否则数据字节是没有意义的。因此,编码在整个过程中都很重要。

这里的第二个问题我没看懂。

如果您将字符集指定为 UTF-8,它可以很好地处理所有字符,但如果我指定另一个字符集就不行,我使用的字体无关紧要,会发生什么?

这里发生的事情是,当您编写charset="iso-8859-1" 时,您还必须实际将文档转换为该编码。您没有这样做,而是将文档保留为 UTF-8 编码。

作为一个小练习,假设我有一个包含以下两个字节的文件:

0xC3 0xB6

使用有关 UTF-8 编码和解码的信息,字节解码到什么代码点?

现在使用this 8859-1 codepage,相同的字节解码成什么?

作为另一个练习,保存两份 HTML 文档,一份使用 charset="iso-8859-1",一份使用 charset="utf-8"。现在使用十六进制编辑器检查两个文件的内容。

现在想象一下,我读取了文件,对它进行了编码,我拥有了所有的代码点,我需要再次保存文件。我需要将其编码保存(\u0000)还是需要先解码以再次转换为字符然后保存?

这取决于需要读取文件的程序。如果程序希望所有非 ASCII 字符都像这样转义,那么您必须以这种方式保存文件。但是用\u 转义字符并不是一件正常的事情。我只在少数地方看到这样做,例如 JSON 数据和 C++ 源代码。

为什么“unicode”这个词有点重,有时被理解为 utf-16?

很大程度上是因为 Microsoft 以这种方式使用该术语。他们这样做是出于历史原因:当他们添加 Unicode 支持时,他们将所有选项命名并设置为“Unicode”,但他们支持的唯一编码是 UTF-16。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2011-02-10
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2012-06-24
    • 2010-12-26
    • 2013-02-25
    • 2019-02-02
    相关资源
    最近更新 更多