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

问题描述 投票:12回答:8

你怎么能设置在.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);

当然,我不希望它是这么简单。我打赌有做一些低层次,非托管的东西;我只是不知道怎么办。

EDIT

我知道我可以用默认替换没有输入。这不是我问。我想了解什么是参与实现我所描述的行为:为用户提供一个可编辑的默认值。我也并不担心输入验证;我的问题无关这一点。

c# .net input console console-application
8个回答
7
投票

我相信,你将不得不手动通过听取各按键管理此:

迅速thown一起例如:

   // 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);
   }

这是相当复杂 - 你必须保持保证光标不出去的范围和手动更新您的缓冲区。


8
投票

这里有一个简单的解决方案:

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


4
投票

或者只测试输入的值,如果它是空把默认值输入。


3
投票

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

    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());
    }

笔记:

  • 适用于输入的只有一条线
  • 您可以定义可编辑文本区域之前什么站(caret参数)
  • 使用您自己的风险,可能仍然存在一些IndexOutOfBound-问题。 ;)

1
投票

简单的解决方案,如果用户输入什么,指定默认:

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;

这被认为是最佳实践,用于处理用户输入。如果你需要分析很多用户输入,使用一个辅助函数。这样做的一个方法是使用方法有一个可为空和返回null如果解析失败。然后,它是非常容易使用null coalescing operator指定一个默认值:

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;

1
投票
  1. 添加引用到国会图书馆“System.Windows.Forms的”你的项目
  2. 添加SendKeys.SendWait(“DefaultText”)的Console.WriteLine命令后,你的到Console.ReadLine命令前

string _weeklycost = "";
Console.WriteLine("Enter weekly cost: ");
System.Windows.Forms.SendKeys.SendWait("135");
_weeklycost = Console.ReadLine();

0
投票

您可以使用这样的helper方法:

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

0
投票

有一个更好的方法来做到这一点,现在,检查出的ReadLine上的NuGet:https://www.nuget.org/packages/ReadLine

  1. install-package Readline
  2. var input = ReadLine.Read("Enter weekly cost: ", "135");

我喜欢用控制台写交互式测试,并具有默认值可以真正帮助的东西。

© www.soinside.com 2019 - 2024. All rights reserved.