ASCII编码、umlauts和accents

3

我有一个需求需要生成ASCII编码的文本文件。我的数据库中充满了带有Umlauts和Accents的希腊、法国和德国字符。这是否可能呢?

string reportString = report.makeReport();
Dictionary<string, string> replaceCharacters = new Dictionary<string, string>();
byte[] encodedReport = Encoding.ASCII.GetBytes(reportString);
Response.BufferOutput = false;
Response.ContentType = "text/plain";
Response.AddHeader("Content-Disposition", "attachment;filename=" + reportName + ".txt");
Response.OutputStream.Write(encodedReport, 0, encodedReport.Length);
Response.End();

当我收到报告字符串时,字符被真实地表示出来。但是当我保存文本文件时,特殊字符会被替换成问号。
据我所知,ASCII标准只适用于美式英语,而UTF 8则适用于国际观众。这个理解正确吗?
我想说的是,如果要求使用ASCII编码,那么我们就无法正确地表示重音和分音符号。
或者,我可能完全错了,说了些愚蠢的话?

1
为了更好地理解所有这些编码问题,您(或您的客户)应该阅读http://www.joelonsoftware.com/articles/Unicode.html。 - Oliver
这是一个不错的参考资料,尽管我在其中发现了一个错误。 ;) - Brady Moritz
7个回答

9

如果一个文件采用标准的ASCII字符集编码,那么就无法表示重音符号和分音符号,因为这些字符在 ASCII 字符集中没有定义。


没错。因此,如果我说我不能给你特殊字符,因为我有一个要求规定我必须以ASCII编码生成这些报告,那么我是在说实话。 - jim
1
只需确保给你这个要求的人理解“ASCII编码”的真正含义。一个典型的不了解Unicode的人可能会认为“ASCII编码”是“文本文件”。 - Lasse V. Karlsen
谢谢Lasse,我认为我的umlauts和重音破坏了他们的导入过程,所以我几乎可以确定是ASCII而不是其他任何东西。 - jim

4
在Unicode出现之前,"代码页"被用来处理这个问题。你可以将代码页看作是Unicode字符和256个能够适配单个字节的值之间的映射(显然,在每个代码页中大多数Unicode字符都缺失)。
原始ASCII代码页仅包括英文字母 - 但是很少有人真正想要原始的7位代码页,他们可能将任何8位字符集称为ASCII。
英文代码页称为Latin-1是ISO-8859-1或Windows-1252(前者是ISO标准,后者是Windows支持的最接近的代码页)。
为了支持不在Latin-1中的字符,您需要使用不同的代码页进行编码,例如:
874Thai
932Japanese
936Chinese (simplified) (PRC, Singapore)
949Korean
950Chinese (traditional) (Taiwan, Hong Kong)
1250Latin (Central European languages)
1251Cyrillic
1252Latin (Western European languages)
1253Greek
1254Turkish
1255Hebrew
1256Arabic
1257Latin (Baltic languages)
1258Vietnamese

UTF-8是一种完全不同的编码方式,它使用可变字节数对整个Unicode字符集进行编码,数字和英文字母与ASCII(和Windows-1252)相同,大多数其他语言的编码为每个字符2到4个字节。

由于英语与ASCII编码相同且字符串中没有嵌入的空值,因此UTF-8与ASCII系统大多数兼容。

将.NET字符串(UTF-16LE)与其他编码之间进行转换可以使用System.Text.Encoding类。

重要提示:最重要的是接收端的系统和发送端的系统使用相同的代码页,否则你会得到乱码。


1
很可能,他们对1252感兴趣-请参阅http://www.cp1252.com了解有关该编码的详细信息。 - Brady Moritz

3
ASCII字符集只包含大写和小写字母A-Z、数字和一些标点符号。没有希腊字符,也没有umlauts或重音符号。
您可以使用被称为“扩展ASCII”的组中的字符集,该字符集使用256个字符而不是128个字符。
使用与ASCII不同的字符集的问题在于,您必须使用正确的字符集,即接收方期望的字符集,否则它将无法正确解释任何扩展字符。
您可以使用Encoding.GetEncoding(...)来创建扩展编码。请参阅Encoding class的参考资料以获取可能的编码列表。

谢谢Guffa,GetEncoding很有趣,只是没有办法知道对方在使用什么。 - jim

2

你说得对。

  • US ASCII是一种7位编码,仅包含英文字符。
  • 如果需要捕获其他字母表中的字符,您需要使用不同的编码方式。UTF-8是一个很好的选择。

2

UTF-8向后兼容ASCII,因此如果您将文件编码为UTF-8,则ASCII客户端可以读取其字符集中的任何内容,Unicode客户端可以读取所有扩展字符。

在ASCII中无法获得所有所需的重音符号; 但是一些重音符号(比如ü)可在“扩展ASCII”(8位)字符集中找到。


有没有一种方法可以使用8位版本而不是7位来进行Encode.Ascii编码? - jim
1
总有一种方法。您可能想要的编码是ANSI 1252或Windows-1252,您可以使用Encoding.GetEncoding(1252)来获取它。这是标准的“Windows”编码。 - Aaronaught

2
其他答案提到的各种编码可以宽泛地描述为扩展ASCII
当您的用户要求ASCII编码时,他们可能正在寻求其中一种编码。
像“如果要求是ASCII编码,我们就无法正确表示重音符号和分音符号”这样的陈述可能会对非技术用户听起来很学究。另一种选择是获取他们想要的示例(可能是他们PC上的ANSI或OEM代码页),确定适当的代码页,并指定它。

2

上述内容只是部分正确。虽然ASCII码中不能编码这些字符,但是可以替代表示它们。这些字符存在的原因是一些打字机和早期计算机无法处理它们。

Ä=Ae
ä=ae
ö=oe
Ö=Oe
ü=ue
Ü=Ue
ß=sz

编辑: Andyraddaz已经编写了代码,用ASCII表示替换了许多Unicode字符。它们可能不适用于某些语言/文化,但至少您不会遇到编码错误。 https://gist.github.com/andyraddatz/e6a396fb91856174d4e3f1bf2e10951c


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