哪些字符不能直接从Cp1252映射到UTF-8?

23

我在几个stackoverflow答案中读到,从Cp1252(也称为Windows-1252;它们是相同的,对吗?)转换为UTF-8时,一些字符不会直接映射(甚至是"无法映射"), 例如这里:https://dev59.com/DmAg5IYBdhLWcg3wm7_6#23399926

请问有人能够详细说明一下吗?这是否意味着,如果我批量/大规模将源代码从cp1252转换为utf-8,我将得到一些最终成为垃圾字符的字符?


你所说的“转换”,是指像这样的代码吗?File.WriteAllText("out.txt", File.ReadAllText("in.txt", Encoding.GetEncoding("Windows-1252", EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback)), Encoding.UTF8) - Tom Blodget
是的,我确实这样认为。 :) - Christian
2个回答

27

这就是Windows 1252编码的样子。

正如您所看到的,字节0x81、0x8D、0x8F、0x90、0x9D并未分配给任何字符。

如果输入文件包含了这些字节,并将其视为Windows 1252编码,则这些字节将被视为无效字符。通常情况下,这意味着输入文件不是Windows 1252格式的。

除此以外,其它所有字节都可以编码成可打印字符或控制字符,并且所有这些字符都存在于Unicode中,因此可以用UTF-8编码方式进行无歧义地编码。

我不知道链接中的答案在试图表达什么,最后一段听起来像是胡言乱语。

以下几点可能会阐明您要了解的内容:

  • UTF-8和Windows 1252在ASCII字符以外完全不兼容

  • 这两种编码均不会将文本编码为特定的字节值,每种编码方式不同

  • 此外,在UTF-8中也有某些无效的字节序列

  • 一般而言,如果您将一个文件视为UTF-8或Windows 1252编码格式的文本文件,但它实际上不是,那么您将会丢失和损坏数据。

您可以在IDE或编辑器中选择文件的编码方式。建议只使用UTF-8编码方式,并将现有的Windows 1252文件转换为UTF-8编码。


10
不错的回答,但需要一个简介:Unicode是Windows-1252的超集。因此,每个作为Windows-1252读取的字符都可以写成UTF-8。 - Tom Blodget
1
@tom-blodget,这不是与Karlos S列出的最后一个要点直接矛盾吗?这只适用于cp1252定义的前128个字符,即ANSI吗? - Christian
@Christian 我不认为有矛盾之处。如果您不知道文件实际上是Windows-1252格式,那么就会出现数据丢失的情况。如果您继续进行转换,则他的观点适用,并且您最初的问题无效。 - Tom Blodget
你说得对。我问了另一个转换问题,有点让他们困惑了。抱歉。 :) - Christian
1
@TomBlodget:UTF-8中的右单引号:0xE2 0x80 0x98。CP1252中的右单引号:0x20 0x18。我认为Karol S在这里的总结是最好的:“一般来说,如果您将文件视为包含以UTF-8或Windows 1252编码的文本,但实际上并非如此,那么您将会丢失和损坏数据”。 - HoldOffHunger

4

有人能否详细说明一下这个问题?

cp1252 解码函数大多数情况下是一个恒等函数。

cp1252    UCP       (UCP = Unicode Code Point)
--------  --------
21        21 (!)    (All numbers in hex)
31        31 (1)
41        41 (A)

这使得似乎期望UCP(而非UTF-8)的内容也会接受cp1252。链接答案的作者指出这并非事实。
cp1252    UCP
--------  --------
80        20AC (€)
85        2026 (…)
99        2122 (™)

异常情况都在80到9F之间,包括这两个数。

接受UCP的内容也会接受iso-8859-1,但不接受cp1252。


这是否意味着,如果我批量将源代码从cp1252转换为utf-8,我会得到一些最终成为垃圾的字符?

不会。cp1252中的每个字符都映射到一个Unicode代码,因此可以使用正确的工具成功地将其转换为UTF-8。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接