Как установить значение ввода по умолчанию в .Net Console App?
Как вы можете установить значение ввода по умолчанию в консольном приложении .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);
Конечно, я не ожидаю, что это будет так просто. Я держу пари, что нужно делать некоторые низкоуровневые неуправляемые вещи; Я просто не знаю, как.
ИЗМЕНИТЬ
Я знаю, что я не могу заменить ввод по умолчанию. Это не то, о чем я прошу. Я пытаюсь научиться тому, что участвовало в достижении описанного мной поведения: предоставление пользователю редактируемого значения по умолчанию. Я также не беспокоюсь о проверке ввода; мой вопрос не имеет к этому отношения.
Ответы
Ответ 1
Я считаю, что вы будете управлять этим вручную, прослушивая каждое нажатие клавиши:
Быстро сложенный пример:
// 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);
}
Это очень важно - вам нужно будет следить за тем, чтобы курсор не вышел из диапазона и вручную обновил ваш буфер.
Ответ 2
Вот простое решение:
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 для полного описания.
Ответ 3
Или... Просто проверьте введенное значение, если оно пусто, введите значение по умолчанию во вход.
Ответ 4
Простое решение, если пользователь ничего не вводит, назначьте значение по умолчанию:
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:
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;
Ответ 5
- Добавить ссылку на сборку библиотеки "System.Windows.Forms" в ваш проект
- Добавить SendKeys.SendWait( "DefaultText" ) сразу после команды Console.WriteLine и перед вашей командой Console.ReadLine
string _weeklycost = "";
Console.WriteLine("Enter weekly cost: ");
System.Windows.Forms.SendKeys.SendWait("135");
_weeklycost = Console.ReadLine();
Ответ 6
Я пошел дальше и завершил подход к реализации Мэтта
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. ;)
Ответ 7
Вы можете использовать вспомогательный метод следующим образом:
public static string ReadWithDefaults(string defaultValue)
{
string str = Console.ReadLine();
return String.IsNullOrEmpty(str) ? defaultValue : str;
}
Ответ 8
Есть гораздо лучший способ сделать это сейчас, посмотрите Readline на nuget: https://www.nuget.org/packages/ReadLine
-
install-package Readline
-
var input = ReadLine.Read("Enter weekly cost", "135");
Мне нравится использовать консоль для написания интерактивных тестов, и наличие значений по умолчанию действительно может помочь.