¿Cómo establecer el valor de entrada predeterminado en la aplicación .Net Console?

¿Cómo se puede establecer un valor de entrada predeterminado en una aplicación de consola .net?

Aquí hay un código de fantasía:

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

Por supuesto, no espero que sea tan simple. Estoy apostando a tener que hacer cosas no gestionadas de bajo nivel; Simplemente no sé cómo.

EDITAR

Sé que no puedo reemplazar ninguna entrada con la predeterminada. Eso no es lo que estoy preguntando. Estoy tratando de APRENDER qué implica el logro del comportamiento que describí: dar al usuario un valor predeterminado editable. Tampoco estoy preocupado por la validación de entrada; Mi pregunta no tiene nada que ver con eso.

Creo que tendrá que gestionar esto manualmente escuchando cada pulsación de tecla:

Ejemplo:

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

Esto es bastante complicado. Deberá asegurarse de que el cursor no esté fuera del rango y actualizar manualmente el búfer.

Aquí hay una solución simple:

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

Sin embargo, no está completo. Algunos caracteres en la cadena de entrada de SendWait tienen un significado especial, por lo que debe escapar de ellos (por ejemplo, +, (,), etc.) Consulte: http://msdn.microsoft.com/en-us/library/system.windows. forms.sendkeys.aspx para una descripción completa.

O … Simplemente pruebe el valor ingresado, si está vacío, ingrese el valor predeterminado en la entrada.

  1. Agregue referencia a la biblioteca de ensamblaje “System.Windows.Forms” a su proyecto
  2. Agregue SendKeys.SendWait (“DefaultText”) inmediatamente después del comando Console.WriteLine y antes del comando Console.ReadLine
 string _weeklycost = ""; Console.WriteLine("Enter weekly cost: "); System.Windows.Forms.SendKeys.SendWait("135"); _weeklycost = Console.ReadLine(); 

Solución simple, si el usuario no ingresa nada, asigne el valor predeterminado:

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

Cuando se trata de entradas de usuario, debe esperar que pueda contener errores. Por lo tanto, puede usar TryParse para evitar una excepción, si el usuario no ha ingresado un número:

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

Esto se consideraría la mejor práctica para manejar las opiniones de los usuarios. Si necesita analizar muchas entradas de usuario, use una función auxiliar para eso. Una forma de hacerlo es usar un método con un valor nulo y devolver el valor nulo si el análisis ha fallado. Entonces es muy fácil asignar un valor predeterminado utilizando el operador de fusión nulo :

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

Luego, leer una entrada y asignar un valor predeterminado es tan fácil como:

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

Puedes usar el método de ayuda de esta manera:

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

Seguí adelante y completé el enfoque de implementación de Matt:

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

Notas:

  • Funciona para una sola línea de entrada
  • Puede definir lo que está delante del área de texto editable (parámetro caret )
  • Utilícelo bajo su propio riesgo, aún puede haber algunos problemas de IndexOutOfBound. 😉