【问题标题】:Reading Unicode with Console.ReadKey使用 Console.ReadKey 读取 Unicode
【发布时间】:2008-11-28 11:14:01
【问题描述】:

是否可以向控制台应用程序提供 Unicode 输入,并通过 Console.ReadKey() 读取 Unicode 字符/字符串?

我知道 Unicode 在通过其他方法读取输入时有效,但不幸的是我需要使用 ReadKey 提供的“拦截”功能。

更新:

将 U+03BB (λ) 等 Unicode 字符粘贴到控制台时,会读取 3 个键。

  1. Alt + NumPad1
  2. Alt + NumPad1
  3. Alt + NumPad8

我试过看看这是否是某种编码,但什么都看不到。

【问题讨论】:

    标签: .net console.readkey


    【解决方案1】:

    不幸的是,Console.ReadKey 只能处理键盘事件。键盘事件只能表示可以在键盘上键入的内容(使用 ConsoleKey 枚举中定义的真实和“虚拟”键)。因此,当使用 ReadKey 时,您只会得到两件事:原始键码,对应于键盘上的键,以及翻译后的字符,即原始键码映射到控制台输入代码页中的 Unicode 字符(和每个代码页最多可以映射 256 个字符)。您无法使用 ReadKey 读取任何其他类型的数据(即无法直接键入和/或在输入代码页中没有映射的字符)。

    此外,当您将 Unicode 字符粘贴到控制台时,ReadKey 使用的 API 会尝试将该字符转换为 Windows ALT+nnn 序列(即,按住 ALT 并在键盘上键入代码点编号)。不幸的是,它首先使用为输入代码页定义的规则翻译字符,因此即使您重新构建代码点编号,您也不会得到粘贴的实际字符,您将得到代码页映射的任何字符到。

    使用 Read 或 ReadLine 时一切正常的原因是它们是基于流的方法,而不是基于键盘的方法。显然,任何字符都可以通过输入流进入,因为没有发生键盘和代码页转换。但是您不能直接使用 ReadKey 获取输入流,只能使用键盘(如果输入流已从键盘以外的其他地方重定向,ReadKey 将彻底失败)。

    如果您手动将控制台 API 与 P/Invoke 一起使用,可能有某种方法可以使用输入流复制 ReadKey 的“拦截”功能,但这并不重要,而且控制台并不是真正设计用于执行此操作的诸如此类的事情,所以您可能会一直与之抗争。


    编辑:话虽如此,您仍然可以实现自己的组合键,以允许通过键盘输入 Unicode 字符——例如输入 CTRL+ALT+U,然后输入四个十六进制数字——您的 ReadKey 例程可以检测到CTRL+ALT+U 然后抓取接下来的四个击键并从中生成一个 int 并将其转换为 char ——但这当然不允许粘贴。

    【讨论】:

    • 我只是偶然发现它实际上适用于Win7 64位。很奇怪。
    • “这是原始键码映射到控制台输入代码页中的 Unicode 字符” 至少在 Vista 上似乎是错误的;相反,我直接得到控制台输入代码页的值 in (例如:在法语控制台上,输入 é 产生 130(其 IBM-850 值)而不是 233 (U+00E9),并且它回显了一个问号——而ReadLine() 正确地回显了é 并产生233)。
    【解决方案2】:

    Console.ReadKey() 返回的 ConsoleKeyInfo 对象有一个名为 KeyChar 的属性,其中包含按下的键或键组合的 Unicode 字符(如果键或键组合具有 Unicode 等效项)。所以……

    char c = Console.ReadKey().KeyChar;
    

    如果键没有 Unicode 等效项(例如,功能键),您将获得一个 '\0' 字符。

    如有必要,您可以使用 StringBuilder 将这些字符连接成一个 Unicode 字符串。

    【讨论】:

    • 是的,你会想到,但它不返回 Unicode,只适用于 ASCII。
    【解决方案3】:

    现在这很奇怪。 IIRC 我的测试是在 32 位上进行的,可能是 Vista。

    现在在Win7 64位上测试了同样的东西,该死的东西有效!

    所以无论是 Vista 还是 32 位错误。

    有人可以确认一下吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      相关资源
      最近更新 更多