【问题标题】:file on UTF-8 and ISO8859-1UTF-8 和 ISO8859-1 文件
【发布时间】:2019-09-17 07:54:25
【问题描述】:

目前我有一个程序,它试图模仿 (linux) file 命令的功能。我用一些字符解析一个 .txt 文件,并将其解释为各自的解释。但是,当涉及到 ISO8859-1(拉丁语 1)时,我很难区分文件。因为它将 ISO8859-1 字符转换为 UTF-8 编码(例如 æ = e6,而是编码为 c3 b8?)。

当我制作这个 .txt 并将其传递到文件中时:

printf "æøå" > test.txt

file test.txt

简单地返回:

UTF-8 Unicode 文本,没有行终止符。

* od -c -tx1 test.txt : 返回 *

0000000 303 246 303 270 303 245
         c3  a6  c3  b8  c3  a5
0000006

谁能向我解释为什么会这样,因为“æøå”前缀包含在 ISO8859-1 编码中,但随后被解释为 UTF8 编码?

【问题讨论】:

  • edit 您的问题并显示od -c -tx1 test.txt 的输出,以确保文件确实包含预期的十六进制值。顺便说一句:虽然您可能想在 C 中实现某些东西,但您的问题与 C 无关,因为它只提到了一些 shell 命令。
  • @Bodo 我在运行命令时更正了问题并显示了文件的输出。将值解释为 2 字节然后将其转换为 UTF8 是有意义的。然而这对我来说很奇怪,因为 ISO8859-1 标准在 160-255 的范围内包括 æøå。
  • 目前还不清楚你觉得这有什么奇怪的地方。如果您的终端编码是 UTF-8,您不希望文件以 UTF-8 创建吗?您预计 ISO8859-1 在什么时候参与?

标签: c linux file


【解决方案1】:

显然您的文件包含 UTF-8 编码。例如c3 a6æ 的UTF-8 编码。

可能您的系统区域设置为 UTF-8。您可以通过运行locale 命令来检查这一点。

要将文件从 UTF-8 转换为 ISO8859-1,您可以使用

recode utf8..iso8859-1 test.txt 

之后你会得到

$ od -c -tx1 test.txt            
0000000 346 370 345
         e6  f8  e5
0000003

正如R.. 所述,如果尚未安装recode,您可能需要安装它。也可以使用iconv,但是这个工具不能就地修改。也可以看看 Best way to convert text files between character sets?https://unix.stackexchange.com/q/10241/330217

【讨论】:

  • 谢谢,这可能是我错过的 :-) 不知道 recode 命令!
  • iconv 命令是执行此操作的标准方法。 recode 是一个随机实用程序,可能会安装也可能不会安装。
【解决方案2】:

Bodo 的回答是正确的,但我认为您问题的根源在于“字符集”一词的歧义。你是对的,所有这些字符都在 ISO-8859-1 中可用的字符集中,但这并不是很相关;这意味着您可以在将文本编码为 ISO-8859-1 时忠实地表示它们。在这里,“集合”一词的歧义(有些人甚至可能会说是误用)就是为什么在现代用法中,这个概念被称为“编码字符集”,或者最好是“字符编码”,以反映重要的方面是可用字符集中的抽象字符如何映射到存储的表示。

作为集合,ISO-8859-1 是 Unicode 的子集,因此是 UTF-8 可表示的字符集的子集。但是作为编码,除了 ASCII 子集之外,它们在任何地方都不一致。 ISO-8859-1 中存在的所有其他字符在 UTF-8 中的表示方式与在 ISO-8859-1 中的表示方式不同;如果不是这种情况,则无法表示超过 256 个字符,因为在 ISO-8859-1 中,所有 256 个字节的含义都已分配(分配给单个字符)。

如 Bodo 的回答中所述,æ 在 UTF-8 中编码为 c3 a6,而在 ISO-8859-1 中编码为 e6

【讨论】:

    猜你喜欢
    • 2017-08-23
    • 2012-05-16
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多