How do I only allow number input into my C# Console Application?

try this code snippet

string _val = "";
Console.Write("Enter your value: ");
ConsoleKeyInfo key;

do
{
    key = Console.ReadKey(true);
    if (key.Key != ConsoleKey.Backspace)
    {
        double val = 0;
        bool _x = double.TryParse(key.KeyChar.ToString(), out val);
        if (_x)
        {
            _val += key.KeyChar;
            Console.Write(key.KeyChar);
        }
    }
    else
    {
        if (key.Key == ConsoleKey.Backspace && _val.Length > 0)
        {
            _val = _val.Substring(0, (_val.Length - 1));
            Console.Write("\b \b");
        }
    }
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);

Console.WriteLine();
Console.WriteLine("The Value You entered is : " + _val);
Console.ReadKey();

This MSDN article explains how to read characters one at a time in a console window. Test each character as it is input with the Char.IsNumber() method, and reject those characters that fail the test.


Here is one approach. It's probably overkill if you're just starting out in C#, since it uses some more advanced aspects of the language. In any case, I hope you find it interesting.

It has some nice features:

  • The ReadKeys method takes an arbitrary function for testing whether the string so far is valid. This makes it easy to reuse whenever you want filtered input from the keyboard (e.g. letters or numbers but no punctuation).

  • It should handle anything you throw at it that can be interpreted as a double, e.g. "-123.4E77".

However, unlike John Woo's answer it doesn't handle backspaces.

Here is the code:

using System;

public static class ConsoleExtensions
{
    public static void Main()
    {
        string entry = ConsoleExtensions.ReadKeys(
            s => { StringToDouble(s) /* might throw */; return true; });

        double result = StringToDouble(entry);

        Console.WriteLine();
        Console.WriteLine("Result was {0}", result);
    }

    public static double StringToDouble(string s)
    {
        try
        {
            return double.Parse(s);
        }
        catch (FormatException)
        {
            // handle trailing E and +/- signs
            return double.Parse(s + '0');
        }
        // anything else will be thrown as an exception
    }

    public static string ReadKeys(Predicate<string> check)
    {
        string valid = string.Empty;

        while (true)
        {
            ConsoleKeyInfo key = Console.ReadKey(true);
            if (key.Key == ConsoleKey.Enter)
            {
                return valid;
            }

            bool isValid = false;
            char keyChar = key.KeyChar;
            string candidate = valid + keyChar;
            try
            {
                isValid = check(candidate);
            }
            catch (Exception)
            {
                // if this raises any sort of exception then the key wasn't valid
                // one of the rare cases when catching Exception is reasonable
                // (since we really don't care what type it was)
            }

            if (isValid)
            {
                Console.Write(keyChar);
                valid = candidate;
            }        
        }    
    }
}

You also could implement an IsStringOrDouble function that returns false instead of throwing an exception, but I leave that as an exercise.

Another way this could be extended would be for ReadKeys to take two Predicate<string> parameters: one to determine whether the substring represented the start of a valid entry and one the second to say whether it was complete. In that way we could allow keypresses to contribute, but disallow the Enter key until entry was complete. This would be useful for things like password entry where you want to ensure a certain strength, or for "yes"/"no" entry.


In a while, I got a solution really short:

double number;
Console.Write("Enter the cost of the item: ");
while (!double.TryParse(Console.ReadLine(), out number))
{
   Console.Write("This is not valid input. Please enter an integer value: ");
}

Console.Write("The item cost is: {0}", number);                          

See you!