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

Ron*_*rby 12 .net c# console input console-application

如何在.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);
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

Viz*_*izu 8

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

public static string ConsoleReadLineWithDefault(string defaultValue)
{
    System.Windows.Forms.SendKeys.SendWait(defaultValue);
    return Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

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


Mat*_*kon 7

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

快速拼凑的例子:

   // 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);
   }
Run Code Online (Sandbox Code Playgroud)

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

  • 事实上,这绝对是迄今为止最好的答案。 (4认同)

Dan*_*ani 5

或者...只是测试输入的值,如果它是空的,则在输入中输入默认值。


Efr*_*ain 5

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

    public static string ReadInputWithDefault(string defaultValue, string caret = "> ")
    {
        Console.WriteLine(); // make sure we're on a fresh line

        List<char> 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<char> 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());
    }
Run Code Online (Sandbox Code Playgroud)

笔记:

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