Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将扩展ASCII字符转换为it';使用Console.ReadKey()方法和ConsoleKeyInfo变量创建正确的演示文稿_C#_Encoding_Console_Ascii_Decoding - Fatal编程技术网

C# 将扩展ASCII字符转换为it';使用Console.ReadKey()方法和ConsoleKeyInfo变量创建正确的演示文稿

C# 将扩展ASCII字符转换为it';使用Console.ReadKey()方法和ConsoleKeyInfo变量创建正确的演示文稿,c#,encoding,console,ascii,decoding,C#,Encoding,Console,Ascii,Decoding,阅读了大约30分钟,并没有在这个网站上找到一些具体的内容 假设在C#中的控制台应用程序中出现以下情况: ConsoleKeyInfo cki; cki = Console.ReadKey(true); Console.WriteLine(cki.KeyChar.ToString()); //Or Console.WriteLine(cki.KeyChar) as well Console.ReadKey(true); 现在,让我们将?放在控制台条目中,并通过控制台将其分配到cki。ReadKe

阅读了大约30分钟,并没有在这个网站上找到一些具体的内容

假设在C#中的控制台应用程序中出现以下情况:

ConsoleKeyInfo cki;
cki = Console.ReadKey(true);
Console.WriteLine(cki.KeyChar.ToString()); //Or Console.WriteLine(cki.KeyChar) as well
Console.ReadKey(true);
现在,让我们将
放在控制台条目中,并通过
控制台将其分配到
cki
。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);

所以,现在这个问题有了更广泛的焦点。。。哪些其他函数只需按下一个键即可完成其执行,并返回按下的内容(ReadKey()的替代项)?我认为没有这样的替代品,但是一个确定的答案是有用的。

问题不在于控制台不知道如何处理Unicode(它知道,而且正确地说)。问题在于您对键盘上按键的理解、按键代码的转换、按键代码的字符转换以及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();
}
它从输入中读取一个键,然后将其附加到字符串中。没什么好担心的,对吧?错了!在美国国际键盘上,您可以执行以下操作:

  • 类型“+a”变为
    a
  • 键入Alt+123将变成
    {
  • 键入Alt+3355将变为←
  • 输入;就像在西班牙语键盘上一样,变为ñ
根据键盘的不同,您会为某个字符按不同的键。有时您会按多个键的组合。上面的第一个组合被记录为
\0a
字符串,keycode
0
(不在枚举中),然后是
ConsoleKey.a
。生成的总字符串现在是
“\0”{←ñ“

Alt+123/3355被记录为键码18(这是Alt键)。在将数字键发送到控制台之前,操作系统将数字键转换为字符

在美国键盘上键入
或在西班牙语键盘上键入
ñ
将显示
ConsoleKey.Oem1
(美国)和
ConsoleKey.Oem3
(西班牙语)

虽然我无法模仿您的行为,但这可能是因为我没有您的屏幕,但您作为控制台字体使用的字体似乎不支持非Unicode字符。在Windows 7上,默认情况下不支持非Unicode字符,我不知道其他Windows版本是否支持。也可能是控制台的代码页设置不正确

总结
字符的组成取决于键盘布局、国际设置中选定的键盘、选定的语言、控制台中选定的代码页,以及是否允许组合键(IME会让情况变得更糟!)。从KeyChar转到普通字符通常很简单,但这取决于系统设置是否相互同步

当我在我的系统上运行您的示例时,我没有相同的行为。但是,我没有您的系统

从一个关键点到一个角色是一件棘手的事情。我建议你不要依靠自己的能力来重新创造系统中已经存在的东西。尝试了解发生了什么是一种好的做法,但实际上,回到
ReadLine
;)

编辑:
我刚刚看到了您的最新编辑。请注意,您可以对输入和输出使用不同的编码(
Console.InputEncoding
Console.OutputEncoding
)。我还想引用另一个线程来强调,当您切换到Unicode时,代码页不再重要。这是最新Windows版本的默认行为:

如果选择Unicode字体,如Lucida Console或ConsoleAs,则 您将能够在控制台上查看和键入Unicode字符, 不管chcp怎么说:

ReadLine()重新配置代码页以正确使用扩展的ASCII和Unicode字符。ReadKey()将其保留为EN-US默认值(代码页850)

只需使用打印所需字符的代码页即可,仅此而已。有关其中一些字符,请参阅:)

因此,对于按下
,解决方案如下:

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);
简单:)

还有一个附带说明:在某些情况下,还需要重新配置
控制台.inpunecoding
属性


另外,请注意,如果您为控制台选择另一种字体(Lucida console/ConsoleAs),这个问题仍然会发生。感谢用户Abel,Lota为此指定了字体更改解决方案,并让我自己发现这是
false

Mmm…好吧,从这里,我想到了一个问题…为什么console.ReadLine()方法?它确实得到了正确的字符,比如ñ、?、并以正确的方式将其存储到字符串或字符中。如果Microsoft只发布其方法的源代码,事情会变得更容易:DWell,他们做到了。关于控制台不支持Unicode,我不相信……两个快速结果正好相反:好吧,是r阅读源代码,发现了两个有趣的差异。Console.ReadKey()使用
buffer.keyEvent.uChar
返回控制台中引入的字符。buffer来自
Win32Native.InputRecord
,它是一种变量类型(没有Win32Native.InputRecord的源可用,完全正确),然后
keyEvent
uChar
将为程序员带来未知:S。情况是缓冲区不能以正确的方式处理扩展的ASCII/Unicode。对于ReadLine()
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);