花了大约30分钟,并没有在这个网站找到一些特定的。
假设以下内容,在C#中,控制台应用程序:
ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
Console.WriteLine(cki.KeyChar.ToString()); //Or Console.WriteLine(cki.KeyChar) as well
Console.ReadKey(true);
现在,让我们将¿
放入控制台条目,并通过cki
将其与Console.ReadKey(true)
对齐。将显示的不是¿
符号,¨
符号是显示的符号。许多其他角色也是如此。示例:ñ
显示¤
,¡
显示-
,´
显示ï
。
现在,让我们使用相同的代码snipplet并为更多Console.ReadLine()
行为添加一些内容:
string data = string.Empty;
ConsoleKeyInfo cki;
for (int i = 0; i < 10; i++)
{
cki = Console.ReadKey(true);
data += cki.KeyChar;
}
Console.WriteLine(data);
Console.ReadKey(true);
问题是,如何以正确的方式处理此问题,最后打印应存储在data
上的正确字符,而不是¨
,¤
,{{1} },-
等?
请注意,我想要一个适用于ï
和ConsoleKeyInfo
的解决方案,而不是使用其他变量类型或读取方法。
编辑:
因为来自Console命名空间的ReadKey()方法依赖于Kernel32.dll,并且它定义性地处理扩展的ASCII和unicode,所以它不再是一个选项,只能找到它返回的有效转换。
处理ReadKey()的不良行为的唯一有效方法是使用在Console.ReadKey()
执行中编写的cki.Key属性并对其应用切换,然后根据什么返回正确的值钥匙被按下了。
例如,要按cki = Console.ReadKey(true)
键来处理:
Ñ
所以,现在问题有一个更广泛的焦点...其他功能只有一个键按下完成它的执行,并返回被按下的内容(ReadKey()的替代品)?我认为没有这样的替代品,但确认的答案将是有用的。
答案 0 :(得分:1)
问题不在于控制台不知道如何处理Unicode(它确实如此,check out this thread)。问题在于您对键盘上的按键的理解,键码的转换,键码到字符的转换以及ReadKey()方法的工作原理。
首先:如果您想要读取连续的字符,请改用Console.ReadLine()
,它会为您完成所有数学运算,并且更好。
让我们来看看以下程序:
Console.WriteLine("Press a key to start (Enter to stop).");
var key = Console.ReadKey();
var allKeys = "";
while(key.Key != ConsoleKey.Enter)
{
Console.WriteLine(key.KeyChar);
allKeys += key.KeyChar;
key = Console.ReadKey();
}
它从输入中读取一个键,而不是将其附加到字符串。没什么好担心的吧?错误!在美国国际键盘上,您可以这样做:
à
{
根据您的键盘,您将为某个角色点击不同的键。有时你会碰到一组钥匙。上面的第一个组合被记录为\0a
字符串和密钥代码0
(不在枚举中),然后是ConsoleKey.A
。现在生成的总字符串为"\0á{←ñ"
。
Alt + 123/3355被记录为键码18(这是Alt键)。将数字键转换为字符是由OS在发送到控制台之前完成的。
在美国键盘上键入;
或在西班牙语键盘上键入ñ
会向您显示ConsoleKey.Oem1
(美国)和ConsoleKey.Oem3
(西班牙语)。
虽然我无法模仿你的行为,但这可能是因为我没有你的屏幕,但是看起来很像你作为Console字体的字体不支持非Unicode字符。在Windows 7上,默认情况下,我不知道其他Windows版本。控制台的代码页也可能设置错误。
总结
角色的构成取决于键盘布局,国际设置中选定的键盘,所选语言,控制台中选定的代码页以及是否允许组合键(IME会变得更糟!)。从KeyChar转到普通字符通常很简单,但取决于您的系统设置是否彼此同步。
当我在我的系统上运行您的示例时,我没有相同的行为。但话说回来,我没有你的系统。
从钥匙转到角色是一件棘手的事。我建议你不要依靠自己的能力来重新发明系统中已有的东西。尝试查看正在发生的事情是一种很好的做法,但实际上,请回到ReadLine
;)。
修改强>
我刚看到你最新的编辑。请注意,您可以对输入和输出(Console.InputEncoding
和Console.OutputEncoding
)进行不同的编码。我还想引用另一个帖子来强调,当你切换到Unicode时,代码页就不再重要了。这是最近Windows版本的默认行为:
如果您选择Unicode字体,例如Lucida Console或Consolas,那么 您将能够在控制台上查看和键入Unicode字符, 不管chcp说什么:
答案 1 :(得分:0)
ReadLine()重新配置代码页以正确使用扩展的ASCII和Unicode字符。 ReadKey()将其保留为EN-US默认值(代码页850)。
只需使用打印所需字符的代码页,即可。有关其中一些内容,请参阅http://en.wikipedia.org/wiki/Code_page:)
因此,对于Ñ
按键,解决方法是:
Console.OutputEncoding = Encoding.GetEncoding(1252); //Also 28591 is valid for `Ñ` key, and others too
string data = string.Empty;
ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
data += cki.KeyChar;
Console.WriteLine(data);
Console.ReadKey(true);
简单:)
并附注:在某些情况下,还需要重新配置Console.InputEncoding
属性!
另请注意,如果您为控制台选择另一种字体(Lucida Console / Consolas),则会出现此问题。 Lotta感谢用户Abel的这一点,他指定改变解决方案的字体并让我自己发现这是false
。