C# Console.ReadLine after ReadKey waits for input two times
Asked Answered
M

3

7

I don't understand what I am missing here, but it seems that Console.ReadKey() is still active and is causing the Console to make me enter twice when using Console.ReadLine() after invoking Console.ReadKey().

I've searched up and down how to escape ReadKey() once a selection was made, but to no avail.

To clarify, this is the behavior which is unexpected: When the console pops up, the user is presented these three options as an example. When the user then types either "u" or "h", the console does not wait; it immediately performs the action without the user having to press Enter.

Did I do something wrong implementing this?

static void Main(string[] args)
{
    Console.WriteLine("u up");
    Console.WriteLine("h home");
    Console.WriteLine("x exit");
    Console.WriteLine("---------------------------------");
    Console.WriteLine("      [Enter Your Selection]");
    Console.WriteLine("---------------------------------");
    Console.Write("Enter Selection: ");
    ConsoleKeyInfo selection;
    Console.TreatControlCAsInput = true;
    int value;
    selection = Console.ReadKey();
    if (char.IsDigit(selection.KeyChar))
    {
        value = int.Parse(selection.KeyChar.ToString());
        value -= 1;
        Console.WriteLine("You've entered {0}", value);
    }
    else
    {
        switch (selection.Key)
        {
            case ConsoleKey.U:
                blurp();
                break;

            case ConsoleKey.H:
                blurp();
                break;

            case ConsoleKey.X:
                System.Environment.Exit(0);
                break;

            default:
                Console.WriteLine("Invalid Input...");
                break;
        }
    }
}

public static void blurp()
{
    Console.WriteLine("");
    Console.Write("Enter Another Value: ");
    string value = Console.ReadLine();
    Console.WriteLine("You've entered {0}", value);
}
Microelement answered 20/2, 2017 at 19:41 Comment(5)
I don't understand the problem. You pause until a key is pressed. If it's U or H, you will then pause waiting for the user to hit Enter. How is that different from what you are experiencing?Botswana
Please, clarify your question, it is hard to understand what you are asking.Staal
if you run the code, when a user selects either u, h, or x, the console does not wait, it performs the action without having to hit enter... in this example, I placed "blurp" method inside the u and h case which then prompts user to type in another value. When the user types in the value and presses enter, console forces you to enter 2x before it quits and never writes "you've entered blah"Microelement
Tested, it is as @JeremyWinslow saing -Lucarne
@Muhammad its fine if the console doesn't wait for enter from the first input. I have no preference. But where the real issue is, is on the second user input ReadLine() within "Blurp".. When the user types something in and presses "enter" key, the follow up writeline doesn't write the "You've entered.. blah", and the user has to type enter key twice... I dont understand what I'm doing wrong here.Microelement
L
5

I tested with this code and got the same behavior:

Console.Write("Enter Selection: ");
Console.TreatControlCAsInput = true;
ConsoleKeyInfo selection = Console.ReadKey();
if (selection.Key == ConsoleKey.U)
{
    Console.Write("Enter Another Value: ");
    string valueStr = Console.ReadLine();
    Console.WriteLine("You've entered {0}", valueStr);
}

The solution is to not use Console.TreatControlCAsInput = true; as this is causing the problems.

More information is in Stack Overflow question TreatControlCAsInput issue. Is this a bug?.

Lucarne answered 20/2, 2017 at 20:14 Comment(1)
yes, confirmed,.. Console.TreatControlCAsInput = true; was the issue. Thank you Tatranksky MedvedMicroelement
S
3

As for the console ending without writing out

 "You've entered ..."

that happens because the program terminates when it leaves the method and the console closes. Either run this without debugging (Ctrl + F5) or add a Console.ReadLine() at the end of your main.

The Console does not wait after the first input because of how the Console.ReadKey() works. If you want to wait for user to press Enter, use ReadLine().

As for the Console.ReadLine() waiting twice before storing the input, that is because you are using

Console.TreatControlCAsInput = true;

which messes with how the Console accepts input internally. Just get rid of it.

Staal answered 20/2, 2017 at 20:15 Comment(0)
B
3

The issue is with the setting:

Console.TreatControlCAsInput = true;

If you comment this line out, everything works as expected. This is a known functionality in C#.

If you still want to set the Console.TreatControlCAsInput = true; you can add a custom method to read the input:

public static string CustomReadLine()
{
    ConsoleKeyInfo cki;
    string value = string.Empty;

    do
    {
        cki = Console.ReadKey();

        value = value + cki.Key;
    } while (cki.Key != ConsoleKey.Enter);

    return value;
}

Change your code

string value = Console.ReadLine();

to make use of this custom function

string value = CustomReadLine();

Please refer to the MSDN article Console.TreatControlCAsInput Property to read input when you have Console.TreatControlCAsInput = true;

Bragg answered 20/2, 2017 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.