【发布时间】:2018-03-21 04:45:45
【问题描述】:
我正在编写一个 .NET Core 控制台应用程序。我想将控制台输入限制为每个输入的一定数量的最大字符。我有一些代码通过使用Console.ReadKey() 而不是Console.ReadLine() 构建一个字符串来做到这一点,一切都可以在Windows 上完美地测试它。然后,当我部署到运行 Raspbian 的 Raspberry Pi 3 时,我很快遇到了各种各样的问题。我记得 Linux 处理行尾的方式与 Windows 不同,而且退格的处理方式似乎也不同。我改变了处理这些的方式,关闭了 ConsoleKey 而不是字符,换行问题消失了,但退格键有时只会注册。此外,有时字符会在我的输入框之外输出到控制台,即使我将 ReadKey 设置为不自行输出到控制台。我是否遗漏了有关 Linux 如何处理控制台输入的内容?
//I replaced my calls to Console.ReadLine() with this. The limit is the
//max number of characters that can be entered in the console.
public static string ReadChars(int limit)
{
string str = string.Empty; //all the input so far
int left = Console.CursorLeft; //store cursor position for re-outputting
int top = Console.CursorTop;
while (true) //keep checking for key events
{
if (Console.KeyAvailable)
{
//true to intercept input and not output to console
//normally. This sometimes fails and outputs anyway.
ConsoleKeyInfo c = Console.ReadKey(true);
if (c.Key == ConsoleKey.Enter) //stop input on Enter key
break;
if (c.Key == ConsoleKey.Backspace) //remove last char on Backspace
{
if (str != "")
{
tr = str.Substring(0, str.Length - 1);
}
}
else if (c.Key != ConsoleKey.Tab && str.Length < limit)
{
//don't allow tabs or exceeding the max size
str += c.KeyChar;
}
else
{
//ignore tabs and when the limit is exceeded
continue;
}
Console.SetCursorPosition(left, top);
string padding = ""; //padding clears unused chars in field
for (int i = 0; i < limit - str.Length; i++)
{
padding += " ";
}
//output this way instead
Console.Write(str + padding);
}
}
return str;
}
【问题讨论】:
-
处理击键的是终端。您将不会收到任何未发送到您的应用程序的击键。换行与此无关。 .NET(和 Core)将使用操作系统的设置。此外,它已经将
\n识别为 Windows 中的换行符 -
Windows 可以识别回车符
\r,而 Linux 只使用换行符\n。我最初是在检查\r,这当然会导致问题。我试图弄清楚是否还有其他类似我没有考虑的差异。我认为这暗示这与终端处理击键的方式不同。我的观点只是调用 ReadKey 在不同的机器上会给出不同的结果,即使我做出完全相同的击键,毫无疑问是因为不同的系统如何处理这些击键。 -
不太确定这有什么意义。在 Linux 上,您仍然按 Enter 键,而不是按 Ctrl+J 来获取 \n。 ReadKey 告诉您按下的键,而不是它产生的字符。因此,只要您使用 Key 而不是 KeyChar 就不会有问题。也许你暴露了一个兼容性问题,这都是相当新的,所以它不是不可想象的。它们支持大约十种不同的 Linux 风格,Raspian 不是其中之一。最好告诉他们,使用New Issue button。
-
@tyjkenn Linux 使用
\n。 Windows 使用\r\n。只有经典 Mac OS使用 来使用\r。但是,这些都与 keystrokes 无关,只有文件、字符串和流。您是否检查了Key 而不是 KeyChar? Key 表示 Shift、Alt、Enter、Down Arrow、Page Down、A、B、C 等。 KeyChar 是如何将其转换为字符的方式。许多键没有等效字符 -
别介意换行的事情。我通过使用 Key 而不是 KeyChar 解决了这个问题,因此我的代码。也许我应该把那部分排除在外,但我认为它会更好地解释我的代码。更改没有修复退格,而那才是真正的问题。那以及当我告诉它不要时它正在输出到控制台的事实。我担心这是兼容性问题,但是有解决方法吗? ReadLine 工作正常,除了我不能限制允许的字符数。
标签: c# raspberry-pi .net-core console-application