【问题标题】:C# UTF-8 string not wanting to convert to ASCII (or something readable anyways)C# UTF-8 字符串不想转换为 ASCII (或任何可读的东西)
【发布时间】:2014-07-23 02:04:45
【问题描述】:

我正在尝试转换从文件中读取的字符串。我不知道文件是如何制作或创建的(编码方式),但这是交易:我得到了这个字符串:

“operaci�n”,应该是“operación”(西班牙语操作)。

我尝试在读取文件时更改编码:

using (StreamReader sr = new StreamReader("file.txt", false, Encoding.ASCII));
using (StreamReader sr = new StreamReader("file.txt", false, Encoding.UTF8));
using (StreamReader sr = new StreamReader("file.txt", false, Encoding.UTF7));
using (StreamReader sr = new StreamReader("file.txt", false, Encoding.UTF32));
using (StreamReader sr = new StreamReader("file.txt", false, Encoding.Unicode));

在保存文件时也是如此(改为 StreamWriter)。我还尝试了一些我在这里找到的奇怪的编码东西以及我自己的一些实验:

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.Default, byteArray))
"operaci?n"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.Unicode, byteArray))

"F\0o\0p\0e\0r\0a\0c\0i\0??n\0"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.UTF32, byteArray))
"F\0\0\0o\0\0\0p\0\0\0e\0\0\0r\0\0\0a\0\0\0c\0\0\0i\0\0\0??\0\0n\0\0\0"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.UTF7, byteArray))
"operaci+//0-n"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray))
"operaci?n"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.BigEndianUnicode, byteArray))
"\0F\0o\0p\0e\0r\0a\0c\0i??\0n\0"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(65001), byteArray))
"operaci???n"

new ASCIIEncoding().GetString(Encoding.Convert(Encoding.ASCII, Encoding.GetEncoding(65001), byteArray))
"operaci???n"

Encoding.GetEncoding(65001).GetString(Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(65001), byteArray))
"operaci�n"

Encoding.GetEncoding(65001).GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray))
"operaci?n"

我也尝试过不同的功能:

public static string utf2ascii(string text)        
{
    ASCIIEncoding ascii = new ASCIIEncoding();
    byte[] byteArray = Encoding.UTF8.GetBytes(text);
    byte[] asciiArray = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray);
    return ascii.GetString(asciiArray);
}

public static string utf2ascii(string text)        
{
    System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
    Byte[] encodedBytes = utf8.GetBytes(text);
    Byte[] convertedBytes = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, encodedBytes);
    System.Text.Encoding ascii = System.Text.Encoding.ASCII;
    return ascii.GetString(convertedBytes);*/
}

无济于事。如您所见,没有任何效果。我还查看了这个应用程序:http://www.codeproject.com/Articles/17201/Detect-Encoding-for-In-and-Outgoing-Text,带有真实字符串的演示程序如下所示:

这让我猜想读写 UTF-8 应该可以工作,但它没有:(。

任何想法都非常欢迎和赞赏!在此先感谢:)


好的,解决了,谢谢大家!原来该文件是由记事本保存在 Windows 1252 中的(出于某种未知原因),因为使用 Sublime Text 或 Notepad++ 保存的文件不会遇到此问题。尽管如此,还是感谢大家的帮助和提醒,因为你们都帮助我清除了我之前在编码方面遇到的许多疑问和陷阱:)

看!

对于那些想查看所涉及的字节的人,这里是特殊字符:

错误代码:[7]: 65533 '�' 但在代码页 1252 中:[7]: 243 'ó'

我的错,这就是它在 Visual Studio 下的显示方式。真正的字节(取自使用 Sublime Text 的十六进制编辑器)在这里,以黄色突出显示:

谢谢大家! :D

【问题讨论】:

  • 请显示所涉及的字节 - 并告诉我们您是如何观察文本的。您不应该在编码之间进行任何转换,尤其是与 ASCII 之间的转换,因为您对非 ASCII 字符感兴趣。
  • 我猜你这里的编码是 Windows-1252 或 Latin-1,你没有试过。
  • 转换为 ACII 不是您想要的。在 .NET ACSII 中是 7 位 - 128 并且不包括ó。 msdn.microsoft.com/en-us/library/…
  • "对于那些想要查看所涉及的字节的人,这里是特殊字符:错误代码:[7]: 65533 '�' 但在代码页 1252 中:[7]: 243 'ó'" 这些是不是字节。涉及的(单个)字节是 243,如果没有指定正确的编码,它本身并不意味着任何东西。
  • 真的,谢谢@KarolS,我以为这就是你想看到的。我已经用十六进制编辑器屏幕截图更新了 OP :)

标签: c# .net encoding utf-8 ascii


【解决方案1】:

很可能是 Windows ANSI 代码页之一。尝试使用Encoding.GetEncoding(1252) 来解码文本。

using (StreamReader sr = new StreamReader("file.txt", false, 
    Encoding.GetEncoding(1252)));

我建议使用 1252,因为这是用于编写西班牙语文本的最合理的 ANSI 代码页。

除此之外,最好的办法是将文件的内容作为字节数组读取。让我们看一下,我们也许可以推断出编码。

【讨论】:

  • 不应该是 Encoding.GetEncoding("windows-1254"); 还是编译器已经知道或推断它是 windows
  • @DJKRAZE Encoding.GetEncoding(1252) 是 Windows-1252
  • +1 谢谢大卫只是仔细检查我有一段时间没有看过任何重载方法我通常在我的问题中使用这个例子
  • 好的,感谢大家的帮助,感谢@David Heffernan 的 Encoding.GetEncoding() 函数,我不知道您可以通过这种方式请求不同的代码页。惊人的!我在 OP 中添加了解决方案和更多细节。谢谢!
【解决方案2】:

使用Encoding.Default(将使用本地计算机的所谓ANSI代码页,对于西班牙语版本的Windows,可能是Windows-1252)或Encoding.GetEncoding("Windows-1252")(保证是Windows-1252)当然)。

编辑:在较新版本的 .NET 上,您可能需要先执行 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);,然后才能使用 Encoding.GetEncoding("Windows-1252")

【讨论】:

  • Encoding.Default 很可能是自找麻烦。独立于语言环境的代码代码页似乎更有可能成为前进的方向。
  • @DavidHeffernan 绝对是。仅当您希望应用程序期望系统“本地”文件时,才应使用 Encoding.Default 之类的东西。例如,如果用户使用记事本创建文件而不考虑代码页,则该文件很可能具有“本地”代码页。但是,如果已知文件始终具有编码 CP1252,则永远不要使用 Encoding.Default
猜你喜欢
  • 2019-11-12
  • 1970-01-01
  • 2021-12-31
  • 2015-08-06
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多