【发布时间】:2013-07-22 08:26:20
【问题描述】:
调用Console.ReadKey() 并在提示符处对长度> 1 的任何剪贴板文本进行粘贴(编辑->粘贴)(比如说“Hello World!”)。
我刚刚意外地发现,在随后调用 Console.ReadKey() 时,向用户显示提示,却没有给出提示!而是读取粘贴文本中的后续字符......没有提示!
底线:要使用 ReadKey,我需要确保(非常确定)当我下次调用 ReadKey 时,它实际上会给用户一个提示。目前,这使得 ReadKey 无法用于此类关键场景。
似乎没有任何方法可以禁用此功能,或者只是清除输入但尚未读出的值。
在我的例子中,这给简单的控制台应用程序带来了严重错误,我在其中循环查找单词“R”代表“RUN”,或任何“E”到“END”。由于接近这个时间,我提示输入文件路径,因此对于已经使用它的用户来说,在这一点上意外粘贴文件路径是相当容易的。问题是 (!!!),如果该文件路径包含一个 'r',它会立即运行。
using System;
namespace Practise1
{
class Program
{
static void Main()
{
RunDialogue2();
}
public static void RunDialogue()
{
while (true) {
Console.WriteLine("Type 'R' to RUN, 'E' to END");
ConsoleKey key = Console.ReadKey().Key;
Console.WriteLine("\r\n");
switch (key) {
case ConsoleKey.R:
Console.WriteLine("RUN! ENGINES BLAST OFF!");
BlastOff();
break;
case ConsoleKey.E:
Console.WriteLine("FINISHED");
return;
default:
Console.WriteLine("INVALID ENTRY, TRY AGAIN");
// we *thought* this would pick up bad input, but not pasted text!
break;
}
}
}
public static void RunDialogue2()
{
while (true) {
Console.WriteLine("Type 'R' to RUN, 'E' to END");
ConsoleKey key = Console.ReadKey().Key;
Console.WriteLine("\r\n");
switch (key) {
case ConsoleKey.R:
Console.WriteLine("RUN! ENGINES BLAST OFF!");
Console.WriteLine("We blasted off at: " + DateTime.UtcNow);
//BlastOff();
break;
case ConsoleKey.E:
Console.WriteLine("FINISHED");
return;
default:
Console.WriteLine("INVALID ENTRY, TRY AGAIN");
// we *thought* this would pick up bad input, but not pasted text!
break;
}
}
}
}
}
如果你有“查理的!”在剪贴板中并粘贴它,这是输出。请注意如何获得多个 RUN!都是无意的。这太可怕了,这对我来说意味着我们永远不能依赖 ReadKey 作为一种可靠的输入法,尤其是当我们认为我们正在验证输入时:
Type 'R' to RUN, 'E' to END
C
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
h
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
a
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
r
RUN! ENGINES BLAST OFF!
We blasted off at: 7/21/2013 11:24:36 PM
Type 'R' to RUN, 'E' to END
l
INVALID ENTRY, TRY AGAIN
Type 'R' to RUN, 'E' to END
e
FINISHED
我知道一个解决方案是改用 Console.ReadLine,但是通过单次按键立即进行交互的能力要快乐得多。有什么办法可以解决这种奇怪的行为吗?
【问题讨论】:
-
我不会说用户没有得到提示。打印提示,然后从输入缓冲区完成读取。通常这是控制台应用程序所需的行为(它允许您一次粘贴对多个问题的响应),但在您的情况下,如 tinstaafl 所示刷新缓冲区。虽然我会在打印提示之前刷新缓冲区。
-
那么谁否决了我的问题?绝对卑鄙。
-
本是对的,因为就像我在我的回答中评论说的那样,我测试了,一切都是正确的
-
@BenVoigt '我不会说用户没有得到提示。' - 就个人而言,我更希望 ReadKey 只接受输入中的一个键,而丢弃其余的。但是,嘿,我不会因为这种意见分歧而投票给人们。我不在乎它的措辞,只要你没有因为一个小的措辞语义问题而否决这个问题。
-
我也没有投反对票。