Domanda

Come è possibile impostare un valore di ingresso predefinito in una console app .net?

Un po 'di codice finzione:

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

Naturalmente, non mi aspetto che sia così semplice. Sto scommettendo su di dover fare un po 'di basso livello, roba non gestito; Io proprio non so come.

Modifica

So di poter sostituire nessun ingresso con il default. Non è quello che sto chiedendo circa. Sto cercando di imparare ciò che è coinvolto nella realizzazione del comportamento che ho descritto: dando all'utente un valore predefinito modificabile. Sono, inoltre, non preoccupato per la convalida dell'input; la mia domanda non ha nulla a che fare con questo.

È stato utile?

Soluzione

Credo che si dovrà gestire questo manualmente con l'ascolto di ogni pressione di un tasto:

rapidamente thown insieme esempio:

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

Questo è abbastanza coinvolto -. Si dovrà mantenere garantire il cursore non va fuori portata e aggiornare manualmente il buffer

Altri suggerimenti

Ecco una soluzione semplice:

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

Non è completa però. Alcuni caratteri della stringa di input SendWait hanno un significato speciale in modo da avere a sfuggire loro (ad es. +, (,), Etc.) Vedere: http://msdn.microsoft.com/en -us / library / system.windows.forms.sendkeys.aspx per una descrizione completa.

Oppure ... Basta verificare il valore immesso, se è vuota mettere il valore di default in input.

Sono andato avanti e completato approccio di implementazione di 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());
    }

Note:

  • Opere per una sola riga di input
  • È possibile definire ciò che sta davanti l'area di testo modificabile (parametro caret)
  • Uso a proprio rischio, non ci possono essere ancora dei IndexOutOfBound-problemi. ;)

Una soluzione semplice, se l'utente immette nulla, assegnare il default:

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

Quando si tratta di input dell'utente, si dovrebbe aspettare che potrebbe contenere degli errori. Così si potrebbe utilizzare TryParse al fine di evitare un'eccezione, se l'utente non ha un numero di ingresso:

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

Questa sarebbe considerata best practice per la gestione di input dell'utente. Se avete bisogno di analizzare molti input dell'utente, utilizzare una funzione di supporto per questo. Un modo per farlo è quello di utilizzare un metodo con un annullabile e restituire null se l'analisi non è riuscita. Allora è molto facile assegnare un valore predefinito utilizzando il nullo coalescenza operatore :

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

Quindi, per leggere un input e assegnare un valore predefinito è facile come:

decimal d = SafeConvert.ToDecimal(Console.ReadLine()) ?? 135;
  1. Aggiungi riferimento per Biblioteca dell'Assemblea "System.Windows.Forms" al progetto
  2. Aggiungi SendKeys.SendWait ( "DefaultText") subito dopo il vostro comando Console.WriteLine e prima che il vostro comando Console.ReadLine

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

È possibile utilizzare metodo di supporto in questo modo:

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

C'è un modo molto migliore per farlo ora, prova anche Readline sul NuGet: https://www.nuget.org/packages/ReadLine

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

Mi piace usare la console per scrivere i test interattivi, e con valori di default può davvero aiutare le cose.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top