Beginner's Guide To Console Input In C#

zacharypatten

Zachary Patten

Posted on August 1, 2020

Beginner's Guide To Console Input In C#

Beginner's Guide To Console Input In C Sharp

Note: I recommend reading this article in order because Examples 1-6 build on each other.

Make sure you have a using System; are the top of your file. Then whenever you want input from the user just use the Console.ReadLine() method.

Example 1: Getting Console Input With Console.ReadLine

using System;

class Program
{
    static void Main()
    {
        Console.Write("Provide input: ");
        string input = Console.ReadLine();
        Console.WriteLine($"Your input: {input}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

So in Example 1, we are successfully getting input from the user. The input is stored in the input variable and is a string data type. The string data type is not a numerical data type, therfore if you wanted to perform math operations on the input such as int doubleInput = 2 * input; it will not work. So the next step is to convert the data type from string to whatever type you need it to be. For this example we will convert the type from string to int.

Example 2: Parsing The Console Input From String To Int32

using System;

class Program
{
    static void Main()
    {
        Console.Write("Please enter an integer: ");
        string input = Console.ReadLine();
        int inputValue = int.Parse(input); // <- This is a bug!
        Console.WriteLine($"Your input: {inputValue}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: There are numerous C# tutorials that use the Convert.ToInt32(...) method, but you should avoid this method. Convert.ToInt32(...) is an old method from before NET Framework 2.0, and we now have better methods to use isntead.

Example 2 shows how you can convert a string to an int using the int.Parse(...) method. It works when the user provides valid input such as 123, but it will throw an exception at runtime if the user provides invalid input such as duck. Thus, this is a bad practice and should be avoided or you may run into bugs in your software. The next step would be to validate the input rather than just trying to directly parse it into an int.

Example 3: Validating Console Input With Int32.TryParse

using System;

class Program
{
    static void Main()
    {
        Console.Write("Please enter an integer: ");
        string input = Console.ReadLine();
        int inputValue;
        bool success = int.TryParse(input, out inputValue);
        if (success)
        {
            Console.WriteLine($"Your input: {inputValue}");
        }
        else
        {
            Console.WriteLine($"Invalid Input.");
        }

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

An out parameter is a way for methods to pass back more than one value. The int.TryParse method is passing back two values to the calling code:

  1. The bool return value that indicates if the parse was successful. In Example 3 we are storing this value in the success variable.
  2. The int typed out parameter that is the resulting value of the parse. In Example 3 we are storing this value in the inputValue variable.

Example 3 shows how to validate that the input from the user using the int.TryParse method. We just need use branching (in this case an if statement) to check if the return value of int.TryParse is true (successful) or false (unsuccessful).

Now we have proper input validation for int data types, but what if you need a valid input in order to continue? The next step is to loop until the user provides valid input.

Example 4: Looping Until User Provides Valid Input

using System;

class Program
{
    static void Main()
    {
        Console.Write("Please enter an integer: ");
        string input = Console.ReadLine();
        int inputValue;
        bool success = int.TryParse(input, out inputValue);
        while (!success)
        {
            Console.WriteLine("Invalid Input. Try again...");
            Console.Write("Please enter an integer: ");
            input = Console.ReadLine();
            success = int.TryParse(input, out inputValue);
        }
        Console.WriteLine($"Your input: {inputValue}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

Example 4 shows how we can continually request input from the user until valid input is provided. When we get past the while loop, we are guaranteed that the inputValue variable has been populated by a valid user input. However, what if we need to validate that value further? What if we want it to only be condsidered valid input if the value is between 0 and 100? The next step is to add additional validation.

Example 5: Additional Validation (0-100)

using System;

class Program
{
    static void Main()
    {
        Console.Write("Please enter an integer (0-100): ");
        string input = Console.ReadLine();
        int inputValue;
        bool success = int.TryParse(input, out inputValue);
        bool valid = success && 0 <= inputValue && inputValue <= 100;
        while (!valid)
        {
            Console.WriteLine("Invalid Input. Try again...");
            Console.Write("Please enter an integer 0 and 100: ");
            input = Console.ReadLine();
            success = int.TryParse(input, out inputValue);
            valid = success && 0 <= inputValue && inputValue <= 100;
        }
        Console.WriteLine($"Your input: {inputValue}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

In Example 5 we added additional validation logic. Now when the loop ends we know that inputValue is a valid int value proviided by the user and it is in the 0-100 range. That is pretty much all you need to know to accept proper int input in your console applications.

Although Example 5 is fully functional, we can shorten it a bit if we want to, but any changes at this point are code style preferences and are not required. In particular though, it would be nice if we created variables for the min and max ranges of the valid user input and used a variable for the message to provide input from the user to prevent duplicated hard-coded string values.

Example 6: Optional Code Style Changes Over Example 5

using System;

class Program
{
    static void Main()
    {
        int min = 0;
        int max = 100;
        int inputValue;
        string prompt = $"Please enter an integer ({min}-{max}): ";
        Console.Write(prompt);
        while (!int.TryParse(Console.ReadLine(), out inputValue) || inputValue < min || max < inputValue)
        {
            Console.WriteLine("Invalid Input. Try Again...");
            Console.Write(prompt);
        }
        Console.WriteLine($"You input the value: {inputValue}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

There are ways to simplify the code even further by making your own methods, but these examples should have given you all you need to get started writing your own interactive console applications in C#. :)

Examples 1-6 give you all the fundamentals you need to get console input from the user, but if you are struggling to modify the examples to fit your needs, maybe some more examples will help. Here is an example where the user can select a mathematical operation from a set of values inside an array.

Example 7: Another Example... Array Of Possible Inputs

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        string[] operators = new[] { "+", "-", "*", "/" };
        string input;
        string prompt = $"Please enter an operator ({string.Join(", ", operators)}): ";
        Console.Write(prompt);
        while (!operators.Contains(input = Console.ReadLine()))
        {
            Console.WriteLine("Invalid Input. Try Again...");
            Console.Write(prompt);
        }
        Operator inputOperator = input switch
        {
            "+" => Operator.Addition,
            "-" => Operator.Subtraction,
            "*" => Operator.Multiplication,
            "/" => Operator.Division,
            _ => throw new NotImplementedException("unexpected operator"),
        };
        Console.WriteLine($"You selected: {inputOperator}");

        Console.WriteLine("Press [enter] To Exit...");
        Console.ReadLine();
    }
}

public enum Operator
{
    Addition,
    Subtraction,
    Multiplication,
    Division,
}
Enter fullscreen mode Exit fullscreen mode

In Example 7 the user may select one of four operators: Addition (+), Subtraction (-), Multiplcation (*), and Division (/). The program will loop until the user selects a valid operator. After a valid operator is selected, the program uses a switch expression to convert the input string into an Operator value. Although it is not necessary to convert the string into an enum, it is a good practice that will result in better code.

You might want to make it easier on the user and let them input multiple values at once. You don't need to, but I would probably recommend making helper methods for this. Lets see an example for handling multiple int inputs at once.

Example 8: Another Example... Multiple Inputs At Once

using System;

class Program
{
    static void Main()
    {
        int[] inputValues;
        string prompt = $"Please enter multiple integers (1, 2, 3): ";
        Console.Write(prompt);
        while (!TryParseIntegerList(Console.ReadLine(), out inputValues))
        {
            Console.WriteLine("Invalid Input. Try Again...");
            Console.Write(prompt);
        }
        Console.WriteLine($"You input the values: {string.Join(", ", inputValues)}");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }

    public static bool TryParseIntegerList(string input, out int[] inputValues)
    {
        inputValues = default;
        string[] splits = input.Split(",");
        int[] result = new int[splits.Length];
        for (int i = 0; i < splits.Length; i++)
        {
            if (!int.TryParse(splits[i].Trim(), out result[i]))
            {
                return false;
            }
        }
        inputValues = result;
        return true;
    }
}
Enter fullscreen mode Exit fullscreen mode

In Example 8 we take in a line of input from the user that should contain multiple int values seperated by commas. If any of the values are not valid int values it is considered invalid and the user must try again. Once we have the input from the user, the first step is to divide the string up into each seperate value, which Example 8 does using the string.Split(...) method. There are other ways to parse strings than using the string.Split(...) method, but that is one of the easiest ones for beginners. Once each input is seperated, we just need to int.TryParse each value to make sure they are all valid, and store them in an array. The string.Trim() method just removes any white space on the front or back of a string so the users can add spaces in their input if they want to. All of the following are acceptable inputs for example:

  • 1,2,3,4,5
  • 1, 2, 3, 4, 5
  • 1,2, 3, 4,5

Example 9: Watching Individual Key Presses With Console.ReadKey

using System;

class Program
{
    static void Main()
    {
        ConsoleKey continueKey = ConsoleKey.C;
        Console.Write($"Press [{continueKey}] to continue...");
        while (Console.ReadKey(true).Key != continueKey)
        {
            // do nothing until they press the correct key
        }
        Console.WriteLine();
        Console.WriteLine($"You pressed {continueKey}.");

        Console.WriteLine("Press [enter] to continue...");
        Console.ReadLine();
    }
}
Enter fullscreen mode Exit fullscreen mode

Example 9 shows how you can watch individual key presses from the user rather than taking in a full string of input. You can do this with the Console.ReadKey(...) method. In this case, Example 9 is requesting that the user press the C key before the program will continue. The Console.ReadKey(...) method also allows you to intercept the input so that the input is accepted but will not be written to the console. Whether or not you want to intercept the input is determined by the parameter on the Console.ReadKey(...) method.

Console Games Examples

Are you wanting to learn how to code games? Even if you aren't interested in game development, making console games is a great way to learn how to program in C#. I have a GitHub repo with examples of console games if you want to give it a look. Many of the games use simple console input techniques like the examples in this gist:
https://github.com/ZacharyPatten/dotnet-console-games

Good Luck!

If you are still relatively new to C# I recommend you stop here. I do not recommend beginners attempt to simplify console input further than the examples in this gist. However, if you want to see some more advanced examples of console input you can expand the following:

Extra: Generic Console Input Helper Method

This is an example of a console input helper method in C# that can make console input one line of code. It is dependent on the Towel nuget package, so you must add the nuget package as a dependency to build and run it. It uses Generics and optional parameters.

using System;
using Towel;
using static Towel.Syntax;

class Program
{
    static void Main()
    {
        // int
        var a = ConsoleHelper.GetInput<int>();
        Console.WriteLine($"You input the value: {a}");
        // double
        var b = ConsoleHelper.GetInput<double>();
        Console.WriteLine($"You input the value: {b}");
        // string
        var c = ConsoleHelper.GetInput<string>();
        Console.WriteLine($"You input the value: {c}");
        // int + overriding the writes
        var d = ConsoleHelper.GetInput<int>(
            prompt: "Insert your favorite integer: ",
            invalidMessage: "Don't be a moron...");
        Console.WriteLine($"You input the value: {d}");
        // custom enum value + overriding the writes
        var e = ConsoleHelper.GetInput<Direction>(
            prompt: "Insert Left or Right: ");
        Console.WriteLine($"You input the value: {e}");
        Console.WriteLine("Press [enter] to exit...");
        Console.ReadLine();
    }
}
public enum Direction
{
    Left,
    Right
}
public static class ConsoleHelper
{
    public static T GetInput<T>(string prompt = null, string invalidMessage = null)
    {
        if (typeof(T) != typeof(string) && !typeof(T).IsEnum && Meta.GetTryParseMethod<T>() == null)
        {
            throw new InvalidOperationException($"Using {nameof(ConsoleHelper)}.{nameof(GetInput)} with a non-supported type.");
        }
    GetInput:
        Console.Write(prompt ?? $"Input a {typeof(T).Name} value: ");
        if (typeof(T) == typeof(string))
        {
            return (T)(object)Console.ReadLine();
        }
        else if (!TryParse(Console.ReadLine(), out T value))
        {
            Console.WriteLine(invalidMessage ?? $"Invalid input. Try again...");
            goto GetInput;
        }
        else
        {
            return value;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
zacharypatten
Zachary Patten

Posted on August 1, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related