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

C# 如何在.Net控制台应用程序中设置默认输入值?,c#,.net,input,console,console-application,C#,.net,Input,Console,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); 当然,我不

如何在.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);
当然,我不希望事情会这么简单。我打赌必须做一些低级的、不受管理的事情;我只是不知道怎么做

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

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

简单解决方案,如果用户未输入任何内容,则指定默认值:

Console.Write("Enter weekly cost: ");
string input = Console.ReadLine();
decimal weeklyCost = String.IsNullOrEmpty(input) ? 135 : decimal.Parse(input);
在处理用户输入时,您应该预料到它可能包含错误。因此,如果用户未输入数字,可以使用TryParse以避免出现异常:

Console.Write("Enter weekly cost: ");
string input = Console.ReadLine(); 
decimal weeklyCost;
if ( !Decimal.TryParse(input, out weeklyCost) ) 
    weeklyCost = 135;
这将被视为处理用户输入的最佳实践。如果您需要解析许多用户输入,请使用helper函数。一种方法是使用具有null的方法,如果解析失败,则返回null。然后,使用以下命令很容易指定默认值:

然后,读取输入并指定默认值非常简单:

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

可以使用以下帮助器方法:

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

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

快速组合示例:

   // 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输入字符串中的某些字符具有特殊含义,因此必须对其进行转义(例如+,(,)等) 有关完整的说明,请参阅

  • 将对程序集库“System.Windows.Forms”的引用添加到项目中
  • 在Console.WriteLine命令之后和Console.ReadLine命令之前立即添加SendKeys.SendWait(“DefaultText”)

  • 我继续并完成了Matt的实施方法:

        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());
        }
    
    公共静态字符串ReadInputWithDefault(字符串defaultValue,字符串插入符号=“>”)
    {
    Console.WriteLine();//请确保我们有新的线索
    List buffer=defaultValue.ToCharArray().Take(Console.WindowWidth-caret.Length-1.ToList();
    Console.Write(插入符号);
    Console.Write(buffer.ToArray());
    Console.SetCursorPosition(Console.CursorLeft,Console.CursorTop);
    ConsoleKeyInfo-keyInfo=Console.ReadKey(true);
    while(keyInfo.Key!=ConsoleKey.Enter)
    {
    开关(keyInfo.Key)
    {
    case ConsoleKey.LeftArrow:
    SetCursorPosition(Math.Max(Console.CursorLeft-1,插入符号.Length),Console.CursorTop);
    打破
    case ConsoleKey.RightArrow:
    SetCursorPosition(Math.Min(Console.CursorLeft+1,插入符号.Length+buffer.Count),Console.CursorTop);
    打破
    case ConsoleKey.主页:
    Console.SetCursorPosition(插入符号长度,Console.CursorTop);
    打破
    案例控制台。结束:
    Console.SetCursorPosition(插入符号长度+缓冲区计数,Console.CursorTop);
    打破
    案例控制台键。退格:
    if(Console.CursorLeft=caret.Length+buffer.Count)
    {
    打破
    }
    var cursorcolumnferdelete=Console.CursorLeft;
    buffer.removet(Console.CursorLeft-caret.Length);
    重写行(插入符号、缓冲区);
    Console.SetCursorPosition(cursorColumnAfterDelete,Console.CursorTop);
    打破
    违约:
    var character=keyInfo.KeyChar;
    if(character<32)//不是可打印的字符
    打破
    var cursorAfterNewChar=Console.CursorLeft+1;
    if(cursorAfterNewChar>Console.WindowWidth | |插入符号长度+缓冲区计数>=Console.WindowWidth-1)
    {
    break;//当前只支持一行输入
    }
    插入(Console.CursorLeft-caret.Length,character);
    重写行(插入符号、缓冲区);
    Console.SetCursorPosition(cursorAfterNewChar,Console.CursorTop);
    打破
    }
    keyInfo=Console.ReadKey(true);
    }
    Console.Write(Environment.NewLine);
    返回新字符串(buffer.ToArray());
    }
    专用静态行(字符串插入符号、列表缓冲区)
    {
    Console.SetCursorPosition(0,Console.CursorTop);
    Write(新字符串(“”,Console.WindowWidth-1));
    Console.SetCursorPosition(0,Console.CursorTop);
    Console.Write(插入符号);
    Console.Write(buffer.ToArray());
    }
    
    注:

    • 仅适用于一行输入
    • 您可以定义可编辑文本区域前的内容(
      caret
      参数)
    • 使用风险自负,可能仍然存在一些索引自动查找问题。;)
        现在有一种更好的方法,请查看nuget上的Readline

      • install package Readline
      • var input=ReadLine.Read(“输入周成本:”,“135”)

      • 我喜欢使用控制台编写交互式测试,使用默认值确实有帮助。

        您将他的虚拟参数保留在了
        ReadLine
        中。您可以按照建议的答案对其进行编码-用户不会关心编码技术。对于理论上的问题,如果有一种方法可以用readline实现的话——可能没有(至少没有记录在案)。但是——我知道,如果你想这么做,我们正在寻找一种方法
        string _weeklycost = "";
        Console.WriteLine("Enter weekly cost: ");
        System.Windows.Forms.SendKeys.SendWait("135");
        _weeklycost = Console.ReadLine();
        
            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());
            }