C UTF-8和ISO8859-1上的文件

C UTF-8和ISO8859-1上的文件,c,linux,file,C,Linux,File,目前我有一个程序,它试图模仿(linux)file命令的功能。我解析带有一些字符的.txt文件,并将其解释为各自的解释。然而,当涉及到ISO8859-1(拉丁语1)时,我很难区分文件。因为它将ISO8859-1字符转换为UTF-8编码(例如,æ=e6编码为c3 b8?) 当我制作并将此.txt文件传递到文件时: 它简单地返回: UTF-8 Unicode文本,不带行终止符 *od-c-tx1 test.txt:返回* 0000000 303 246 303 270 303 245 c3 a6 c

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

当我制作并将此.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编码

显然,您的文件包含UTF-8编码。例如,
c3a6
æ
的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
如中所述,如果尚未安装,则可能必须安装
重新编码
。您也可以使用
iconv
,但此工具无法进行就地修改。另见
博多的回答是正确的,但我认为你问题的根源在于“字符集”这个术语的模糊性。所有这些字符都在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

请回答您的问题并显示
od-c-tx1 test.txt
的输出,以确保该文件确实包含预期的十六进制值。顺便说一句:虽然您可能想在C中实现一些东西,但您的问题与C无关,因为它只提到一些shell命令。@Bodo我更正了这个问题,并在运行命令时显示了文件的输出。它将值解释为2字节,然后将其转换为UTF8,这很有意义。然而,这对我来说很奇怪,因为ISO8859-1标准包括160-255范围内的æå。不清楚你觉得这有什么奇怪之处。如果您的终端编码是UTF-8,您不希望文件以UTF-8创建吗?您希望ISO8859-1在什么时候参与进来?谢谢,这可能是我错过的:-)不知道recode命令!
iconv
命令是执行此操作的标准方法
recode
是一个随机实用程序,可能安装也可能未安装。
recode utf8..iso8859-1 test.txt