C# Console application – remember users previous input (use up and down arrow keys)

Who’s using console applications these days? Well I’m, console applications are very convenient for testing or performing repetitive actions quickly.

One downside of the Console within the .Net Framework is the lack of remembering the (previous) user input. Just like cmd or PowerShell I want to use the arrow keys for scrolling through your previous inputted items.

I had some spare time and did some research (Googling) but I could not find an easy solution. So I have created below code which can reuse your previous input, later on. Without creating new lines in the console or remove your question line i.e.:

Question: What’s your favourite color:
Answer: Blue

First of all for this to work you have to create a Queue object, which will store the latest values at the beginning of the queue. I have created this object into a Class named GlobalSettings:

public static Queue<string> InputQueue = new Queue<string>();

Next is asking the user your question (‘What’s your favourite color: ‘)


string Question = "What's your favourite color: ");
string Answer = ReadConsole(Question);
GlobalSettings.InputQueue.Enqueue(Answer);

Just add below code and the magic will happen 😉 everytime a user will add an answer it will be saved to the queue and can be reused in the next question.

using Client.Models;
using System;
using System.Linq;

namespace Client.Functions
{
    public class ConsoleExtension
    {
        /// <summary>
        /// In this function we will read and process the user input
        ///  1. Up and Down arrow keys to read the queue (history of input)
        ///  2. Right and Left arrow keys to scroll through the command line, but no further then the Question
        ///  3. Backspace to remove chars, but no further then the Question
        ///  4. Default, process each char
        ///  5. Enter exit and return the answer
        /// </summary>
        /// <param name="Question"></param>
        /// <returns>Answer of the user</returns>
        static string ReadConsole(string Question)
        {
            string AnswerStringBuilder = "";
            int CounterOfQueue = 0;

            while (true)
            {
                // loop until Enter key is pressed
                ConsoleKeyInfo KeyInfoPressed = Console.ReadKey();
                switch (KeyInfoPressed.Key)
                {
                    case ConsoleKey.UpArrow:
                        // present the member (from end) in the queue not further then the queue size
                        if (CounterOfQueue == 0)
                        {
                            CounterOfQueue = GlobalSettings.InputQueue.Count;
                            AnswerStringBuilder = GlobalSettings.InputQueue.ElementAt(CounterOfQueue - 1);
                            ClearConsole(Question, AnswerStringBuilder);
                            CounterOfQueue--;
                        }
                        else
                        {
                            if (CounterOfQueue == 0)
                            {
                                CounterOfQueue = 0;
                                ClearConsole(Question, "");
                                AnswerStringBuilder = "";
                            }
                            else
                            {
                                AnswerStringBuilder = GlobalSettings.InputQueue.ElementAt(CounterOfQueue - 1);
                                ClearConsole(Question, AnswerStringBuilder);
                                CounterOfQueue--;
                            }
                        }
                        break;

                    case ConsoleKey.DownArrow:
                        // present the member (from begin) in the queue not further then the queue size
                        if (GlobalSettings.InputQueue.Count > CounterOfQueue)
                        {
                            AnswerStringBuilder = GlobalSettings.InputQueue.ElementAt(CounterOfQueue);
                            ClearConsole(Question, AnswerStringBuilder);
                            CounterOfQueue++;
                        }
                        else
                        {
                            CounterOfQueue = 0;
                            ClearConsole(Question, "");
                            AnswerStringBuilder = "";
                        }
                        break;

                    case ConsoleKey.LeftArrow:
                        // move the cursor to the correct position, not further then the end of the question
                        if (Console.CursorLeft > Question.Length)
                        {
                            Console.SetCursorPosition(Console.CursorLeft - 2, Console.CursorTop);
                        }
                        break;

                    case ConsoleKey.RightArrow:
                        // move the cursor to the correct position, not further then the end of the buffer
                        if (Console.CursorLeft < Console.BufferWidth)
                        {
                            Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
                        }
                        break;

                    case ConsoleKey.Backspace:
                        // Backspace, remove the char until we reach the question, we can't delete the question
                        if (Console.CursorLeft > Question.Length - 1)
                        {
                            Console.Write(new string(' ', 1));
                            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
                            AnswerStringBuilder = AnswerStringBuilder.Remove(AnswerStringBuilder.Length - 1, 1);
                        }
                        else
                        {
                            Console.SetCursorPosition(Question.Length, Console.CursorTop);
                        }
                        break;

                    case ConsoleKey.Delete:
                        break;

                    default:
                        // just add the char to the answer building string
                        AnswerStringBuilder = AnswerStringBuilder + KeyInfoPressed.KeyChar.ToString();
                        ClearConsole(Question, AnswerStringBuilder);
                        break;

                    case ConsoleKey.Enter:
                        // exit this routine and return the Answer to process further
                        return AnswerStringBuilder;
                }
            }
        }


        /// <summary>
        /// In this function we will clear the currentline:
        ///  1. we will set the cursur position to the 1 position
        ///  2. clear the line question length will be substracted from line width
        ///  3. reset the cursur position to 1 again
        ///  4. input the question and answer of the user
        /// </summary>
        /// <param name="Question">Question which is served at the user</param>
        /// <param name="Answer">Answer of the user</param>
        static void ClearConsole(string Question, string Answer)
        {
            Console.SetCursorPosition(0, Console.CursorTop);
            Console.Write(new String(' ', Console.BufferWidth - Question.Length));
            Console.SetCursorPosition(0, Console.CursorTop);
            Console.Write(Question + Answer);
        }
    }
}

A very happy New Year,

Daniel Nikolic

Is interested in everything connected to technology. Has a passion for cloud, virtualization and software development. Always finds appropriate IT solutions for customers that match their needs strategically, technically and financially.


Core qualities

Quick thinker, result driven, ambitious, customer-friendly, enthusiastic

Hobbies
Running, listening to music, good food and doing fun things with family

Job description
CTO PepperByte, LoadGen, and BlueParq

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *