【问题标题】:Encoding of Console.ReadConsole.Read 的编码
【发布时间】:2016-01-17 12:56:23
【问题描述】:

我目前正在开发一个从控制台获取输入的应用程序同时也支持输入重定向。为此,我通常使用Console.Read 来接收单个字符。但是,我找不到任何说明它使用什么编码的资源(ASCII?UTF-16?UTF-8??),并且Console.InputEncoding 似乎只影响来自控制台的直接输入。它使用什么编码,如果可能的话,我怎么能改变它?

编辑: 文本文件以 UTF-8 编码,但我只想知道如何读取它。

【问题讨论】:

  • 这是其他程序使用的编码,您将其输出重定向到您的输入。如果它是一个文本文件,那么它就是创建该文件的程序使用的任何文本编码。因此,除非您对该程序或文件有确凿的事实,否则您只是不知道。它是如此不可猜测的事实使得 I/O 重定向成为一个主要的错误工厂,你最好不要依赖它。这是一个应该保留在 Unix 中的 Unix 功能 :)
  • 不知道。为什么要投票?

标签: c# .net encoding console


【解决方案1】:

由于我没有收到太多回应,我决定自己做一些测试。我写了一个不同字节宽度的 UTF-8 文件:

0123456789: Basic Latin, 1 byte
٠١٢٣٤٥٦٧٨٩: Arabic, 2 bytes
₀₁₂₃₄₅₆₇₈₉: Superscripts and Subscripts, 3 bytes
??????????: Mathematical Alphanumeric Symbols, 4 bytes

对于那些不能正确阅读的人,这里是一个 hexdump:

0000000: 3031 3233 3435 3637 3839 3a20 4261 7369  0123456789: Basi
0000010: 6320 4c61 7469 6e2c 2031 2062 7974 650a  c Latin, 1 byte.
0000020: d9a0 d9a1 d9a2 d9a3 d9a4 d9a5 d9a6 d9a7  ................
0000030: d9a8 d9a9 3a20 4172 6162 6963 2c20 3220  ....: Arabic, 2 
0000040: 6279 7465 730a e282 80e2 8281 e282 82e2  bytes...........
0000050: 8283 e282 84e2 8285 e282 86e2 8287 e282  ................
0000060: 88e2 8289 3a20 5375 7065 7273 6372 6970  ....: Superscrip
0000070: 7473 2061 6e64 2053 7562 7363 7269 7074  ts and Subscript
0000080: 732c 2033 2062 7974 6573 0af0 9d9f 8ef0  s, 3 bytes......
0000090: 9d9f 8ff0 9d9f 90f0 9d9f 91f0 9d9f 92f0  ................
00000a0: 9d9f 93f0 9d9f 94f0 9d9f 95f0 9d9f 96f0  ................
00000b0: 9d9f 973a 204d 6174 6865 6d61 7469 6361  ...: Mathematica
00000c0: 6c20 416c 7068 616e 756d 6572 6963 2053  l Alphanumeric S
00000d0: 796d 626f 6c73 2c20 3420 6279 7465 730a  ymbols, 4 bytes.

现在,我编写了一个简单的程序来输出它读取的代码点:

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Codepoints:");
        for (int cur = Console.Read(); cur != -1; cur = Console.Read())
            Console.WriteLine("U+{0:X4}", cur);
    }
}

现在,这是在我的测试文件上运行时的输出:

Codepoints:
U+0030
U+0031
U+0032
U+0033
U+0034
U+0035
U+0036
U+0037
U+0038
U+0039
<cut>
U+0660
U+0661
U+0662
U+0663
U+0664
U+0665
U+0666
U+0667
U+0668
U+0669
<cut>
U+2080
U+2081
U+2082
U+2083
U+2084
U+2085
U+2086
U+2087
U+2088
U+2089
<cut>
U+D835
U+DFCE
U+D835
U+DFCF
U+D835
U+DFD0
U+D835
U+DFD1
U+D835
U+DFD2
U+D835
U+DFD3
U+D835
U+DFD4
U+D835
U+DFD5
U+D835
U+DFD6
U+D835
U+DFD7
<cut>

(正如我所怀疑的,添加Console.InputEncoding = Encoding.UTF8; 对输出没有影响。)如您所见,它可以很好地读取基本多语言平面中的字符。但是,当您开始进入辅助平面时,它的行为类似于 UTF-16 并开始输出代理字符。然而,这些代理仍然正确地编码了原始字符,这让我得出了我的结论:

Console.Read 可以读取 UTF-8,但以 UTF-16 输出。

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2012-08-31
    相关资源
    最近更新 更多