如何在.Net控制台应用程序中设置默认输入值?

如何在.net控制台应用程序中设置默认输入值?

这是一些伪装代码:

Console.Write("Enter weekly cost: "); string input = Console.ReadLine("135"); // 135 is the default. The user can change or press enter to accept decimal weeklyCost = decimal.Parse(input); 

当然,我不希望它如此简单。 我打算不得不做一些低级的,无管理的东西; 我只是不知道如何。

编辑

我知道我可以用默认值替换没有输入。 这不是我要问的问题。 我试图了解实现我所描述的行为所涉及的内容:为用户提供可编辑的默认值。 我也不担心输入validation; 我的问题与此无关。

我相信您可以通过收听每个按键来手动管理:

迅速拼凑在一起的例子:

  // write the initial buffer char[] buffer = "Initial text".ToCharArray(); Console.WriteLine(buffer); // ensure the cursor starts off on the line of the text by moving it up one line Console.SetCursorPosition(Console.CursorLeft + buffer.Length, Console.CursorTop - 1); // process the key presses in a loop until the user presses enter // (this might need to be a bit more sophisticated - what about escape?) ConsoleKeyInfo keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { switch (keyInfo.Key) { case ConsoleKey.LeftArrow: ... // process the left key by moving the cursor position // need to keep track of the position in the buffer // if the user presses another key then update the text in our buffer // and draw the character on the screen // there are lots of cases that would need to be processed (backspace, delete etc) } keyInfo = Console.ReadKey(true); } 

这非常复杂 – 您必须确保光标不会超出范围并手动更新缓冲区。

这是一个简单的解决方案:

 public static string ConsoleReadLineWithDefault(string defaultValue) { System.Windows.Forms.SendKeys.SendWait(defaultValue); return Console.ReadLine(); } 

但它并不完整。 SendWait输入字符串中的某些字符具有特殊含义,因此您必须转义它们(例如。+,(,)等)请参阅: http : //msdn.microsoft.com/en-us/library/system.windows。 forms.sendkeys.aspx获取完整说明。

或者……只测试输入的值,如果它为空则将默认值输入输入。

  1. 将程序集库“System.Windows.Forms”的引用添加到项目中
  2. 在Console.WriteLine命令之后和Console.ReadLine命令之前立即添加SendKeys.SendWait(“DefaultText”)
 string _weeklycost = ""; Console.WriteLine("Enter weekly cost: "); System.Windows.Forms.SendKeys.SendWait("135"); _weeklycost = Console.ReadLine(); 

简单的解决方案,如果用户没有输入,则分配默认值:

 Console.Write("Enter weekly cost: "); string input = Console.ReadLine(); decimal weeklyCost = String.IsNullOrEmpty(input) ? 135 : decimal.Parse(input); 

处理用户输入时,您应该预期它可能包含错误。 因此,如果用户没有输入数字,您可以使用TryParse来避免exception:

 Console.Write("Enter weekly cost: "); string input = Console.ReadLine(); decimal weeklyCost; if ( !Decimal.TryParse(input, out weeklyCost) ) weeklyCost = 135; 

这将被视为处理用户输入的最佳实践。 如果需要解析许多用户输入,请使用辅助函数。 一种方法是使用一个可以为null的方法,如果解析失败则返回null。 然后使用空合并运算符分配默认值非常容易:

 public static class SafeConvert { public static decimal? ToDecimal(string value) { decimal d; if (!Decimal.TryParse(value, out d)) return null; return d; } } 

然后,读取输入并分配默认值就像:

 decimal d = SafeConvert.ToDecimal(Console.ReadLine()) ?? 135; 

您可以使用这样的帮助方法:

 public static string ReadWithDefaults(string defaultValue) { string str = Console.ReadLine(); return String.IsNullOrEmpty(str) ? defaultValue : str; } 

我继续完成了马特的实施方法:

  public static string ReadInputWithDefault(string defaultValue, string caret = "> ") { Console.WriteLine(); // make sure we're on a fresh line List buffer = defaultValue.ToCharArray().Take(Console.WindowWidth - caret.Length - 1).ToList(); Console.Write(caret); Console.Write(buffer.ToArray()); Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop); ConsoleKeyInfo keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { switch (keyInfo.Key) { case ConsoleKey.LeftArrow: Console.SetCursorPosition(Math.Max(Console.CursorLeft - 1, caret.Length), Console.CursorTop); break; case ConsoleKey.RightArrow: Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, caret.Length + buffer.Count), Console.CursorTop); break; case ConsoleKey.Home: Console.SetCursorPosition(caret.Length, Console.CursorTop); break; case ConsoleKey.End: Console.SetCursorPosition(caret.Length + buffer.Count, Console.CursorTop); break; case ConsoleKey.Backspace: if (Console.CursorLeft <= caret.Length) { break; } var cursorColumnAfterBackspace = Math.Max(Console.CursorLeft - 1, caret.Length); buffer.RemoveAt(Console.CursorLeft - caret.Length - 1); RewriteLine(caret, buffer); Console.SetCursorPosition(cursorColumnAfterBackspace, Console.CursorTop); break; case ConsoleKey.Delete: if (Console.CursorLeft >= caret.Length + buffer.Count) { break; } var cursorColumnAfterDelete = Console.CursorLeft; buffer.RemoveAt(Console.CursorLeft - caret.Length); RewriteLine(caret, buffer); Console.SetCursorPosition(cursorColumnAfterDelete, Console.CursorTop); break; default: var character = keyInfo.KeyChar; if (character < 32) // not a printable chars break; var cursorAfterNewChar = Console.CursorLeft + 1; if (cursorAfterNewChar > Console.WindowWidth || caret.Length + buffer.Count >= Console.WindowWidth - 1) { break; // currently only one line of input is supported } buffer.Insert(Console.CursorLeft - caret.Length, character); RewriteLine(caret, buffer); Console.SetCursorPosition(cursorAfterNewChar, Console.CursorTop); break; } keyInfo = Console.ReadKey(true); } Console.Write(Environment.NewLine); return new string(buffer.ToArray()); } private static void RewriteLine(string caret, List buffer) { Console.SetCursorPosition(0, Console.CursorTop); Console.Write(new string(' ', Console.WindowWidth - 1)); Console.SetCursorPosition(0, Console.CursorTop); Console.Write(caret); Console.Write(buffer.ToArray()); } 

笔记:

  • 仅适用于一行输入
  • 您可以定义可编辑文本区域之前的内容( caret参数)
  • 使用风险自负,可能仍存在一些IndexOutOfBound问题。 ;)