Trouble reading only one character from ReadKey() - c#

I'm new to c# and I'm creating a little console application. I want a smooth menu system changing on key inputs. I have a loop registering
public void MainMenu()
{
ConsoleKeyInfo _key;
do
{
Console.WriteLine("Main Menu");
Console.WriteLine("Press 1 for cars");
Console.WriteLine("Press 2 for planes");
Console.WriteLine("Press 3 for boats");
Console.WriteLine("Enter 'q' to exit");
_key = Console.ReadKey();
switch ((char)_key.Key)
{
case '1':
{
Console.Clear();
CarMenu();
break;
}
case '2':
{
Console.Clear();
PlaneMenu();
break;
}
case '3':
{
Console.Clear();
BoatMenu();
break;
}
case 'Q':
{
Environment.Exit(0);
break;
}
default:
{
Console.WriteLine("No options to that key...");
Console.WriteLine("-------------------------\n\n");
break;
}
}
} while (true);
}
public void CarMenu()
{
do
{
Console.Clear();
Console.WriteLine("Car menu");
Console.WriteLine("Press 1 to list all cars");
Console.WriteLine("Press 2 to list single car");
Console.WriteLine("Press 3 to register a new car");
Console.WriteLine("Press 0 for main menu");
Console.WriteLine("Enter 'q' to exit");
_key = Console.ReadKey();
Console.WriteLine((char)_key.Key);
Console.ReadKey();
switch ((char)_key.Key)
{
case '1':
{
Console.Clear();
_handler.listAllDevices();
break;
}
case '2':
{
Console.Clear();
PlaneMenu();
break;
}
case '3':
{
Console.Clear();
BoatMenu();
break;
}
case '0':
{
Console.Clear();
MainMenu();
break;
}
case 'Q':
{
Environment.Exit(0);
break;
}
default:
{
Console.WriteLine("No options to that key...");
Console.WriteLine("-------------------------\n\n");
break;
}
}
} while (true);
}
I have several cases, amongst case '1' and case 'Q'. First time I press any of them it works but next time I need to press 1 twice and q thrice. No matter SHIFT + q or Caps Lock. I tried a number of different solutions, clearing buffers etc but haven't really accomplished much.
Seems strange to me but I guess I'm missing something. Any clues? Thanks

So the full snippet is:
{
private static void Main(string[] args)
{
do
{
Console.WriteLine("Main Menu");
Console.WriteLine("Press 1 for cars");
Console.WriteLine("Press 2 for planes");
Console.WriteLine("Press 3 for boats");
Console.WriteLine("Enter 'q' to exit");
ConsoleKeyInfo _key = Console.ReadKey();
switch ((char) _key.Key)
{
case '1':
{
Console.Clear();
CarMenu();
break;
}
case '2':
{
Console.Clear();
//PlaneMenu();
break;
}
case '3':
{
Console.Clear();
//BoatMenu();
break;
}
case 'Q':
{
Environment.Exit(0);
break;
}
default:
{
Console.WriteLine("No options to that key...");
Console.WriteLine("-------------------------\n\n");
break;
}
}
} while (true);
}
public static void CarMenu()
{
do
{
Console.Clear();
Console.WriteLine("Car menu");
Console.WriteLine("Press 1 to list all cars");
Console.WriteLine("Press 2 to list single car");
Console.WriteLine("Press 3 to register a new car");
Console.WriteLine("Press 0 for main menu");
Console.WriteLine("Enter 'q' to exit");
ConsoleKeyInfo _key = Console.ReadKey();
Console.WriteLine((char) _key.Key);
//Console.ReadKey();
switch ((char) _key.Key)
{
case '1':
{
Console.Clear();
Console.WriteLine("1");
//_handler.listAllDevices();
break;
}
case '2':
{
Console.Clear();
Console.WriteLine("1");
break;
}
case '3':
{
Console.Clear();
Console.WriteLine("1");
break;
}
case '0':
{
Console.Clear();
return;
}
case 'Q':
{
Environment.Exit(0);
return;
}
default:
{
Console.WriteLine("No options to that key...");
Console.WriteLine("-------------------------\n\n");
break;
}
}
} while (true);
}
}
As you can see, I have coomented second call to ReadKey(). This was original problem.

Related

How to execute logic if switch value is other than the choices?

This might be the most simple question of all time but how do you make it so that if I write something that isn't one of the choices 1,2,3,4 the program will say "Wrong choice, try again" ?
For example: If the user types in "36" the program should say "Wrong choice, try again"
I know I can use if and if else for choice 1,2,3,4 and then use else for it to write "Wrong choice" but is there any shorter/easier way of doing it?
using System;
namespace atmtest
{
class Program
{
public static void Main()
{
int choice;
while (true)
{
Console.WriteLine("----------------------------");
Console.WriteLine("Welcome");
Console.WriteLine("----------------------------");
Console.WriteLine("1) Example 1");
Console.WriteLine("2) Example 2");
Console.WriteLine("3) Example 3");
Console.WriteLine("--------------------------------");
Console.WriteLine("Choose one of the 3 options");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
Console.Clear();
Console.WriteLine("You chose 1");
break;
case 2:
Console.Clear();
Console.WriteLine("You chose 2");
break;
case 3:
Console.Clear();
Console.WriteLine("You chose 3");
break;
}
}
}
}
}
You just set the default in the switch statement, like:
switch (choice) {
case 1:
Console.Clear();
Console.WriteLine("You chose 1");
break;
case 2:
Console.Clear();
Console.WriteLine("You chose 2");
break;
case 3:
Console.Clear();
Console.WriteLine("You chose 3");
break;
default:
Console.Clear();
Console.WriteLine("Wrong option!");
break;
}

Returning back to the beginning of a block of code?

I need to return back to the beginning of the code shown here after a user enters the wrong key. Is there any simple line of code that will just return back to another line? As you can see I already have an if statement set up so I can just add something that can return back to the beginning or to another area in my code. I am really quite new to c# and programming in general. I really just don't want to have to enter all the code again into another if statement that would produce the same issue. I would preferably like to have the code just run again after a user enters a wrong key, because then they can re-read it without having to start from scratch again.
//Runs battle interactive
Console.WriteLine("");
Console.WriteLine("You have encountered a simple guard! He deals 2 damage per attack and has 1 HP.");
Console.WriteLine("You currently have: " + Program.Inventory);
Console.WriteLine("Choose a weapon!");
var input2 = Console.ReadKey();
//Key checker for items
switch (input2.Key)
{
case ConsoleKey.D1:
Console.WriteLine("");
if (Items.iniFists == true)
{
Console.WriteLine("You have attacked with your Fists for 1 DMG!");
}
else
{
//this will never run, just a placeholder
Console.WriteLine("You Don't have your fists!");
switch (input2.Key)
{
case ConsoleKey.D1:
Console.WriteLine("");
if (Items.iniFists == true)
{
Console.WriteLine("You have attacked with your Fists for 1 DMG!");
}
else
{
//this will never run, just a placeholder
Console.WriteLine("You Don't have your fists!");
}
break;
case ConsoleKey.D2:
Console.WriteLine("");
if (Items.iniLongsword == true)
{
Console.WriteLine("You have chosen to attack with the Longsword for 2 DMG!");
}
else
{
Console.WriteLine("You don't have a longsword!");
}
break;
case ConsoleKey.D3:
Console.WriteLine("");
if (Items.iniBow == true)
{
Console.WriteLine("You have chosen to attack with the Bow for 3 DMG!");
}
else
{
Console.WriteLine("You don't have a Bow!");
}
break;
case ConsoleKey.D4:
Console.WriteLine("");
if (Items.iniLightstaff == true)
{
Console.WriteLine("You have chosen to attack with the Lightstaff for 4 DMG!");
}
else
{
Console.WriteLine("You don't have a Lightstaff!");
}
break;
case ConsoleKey.D5:
Console.WriteLine("");
Console.WriteLine("You can't attack with an Apple!");
break;
case ConsoleKey.D6:
Console.WriteLine("");
Console.WriteLine("You can't attack with a Golden Key!");
break;
case ConsoleKey.D7:
Console.WriteLine("");
Console.WriteLine("You can't attack with a Steak!");
break;
}
}
break;
case ConsoleKey.D2:
Console.WriteLine("");
if (Items.iniLongsword == true)
{
Console.WriteLine("You have chosen to attack with the Longsword for 2 DMG!");
}
else
{
Console.WriteLine("You don't have a longsword!");
}
break;
case ConsoleKey.D3:
Console.WriteLine("");
if (Items.iniBow == true)
{
Console.WriteLine("You have chosen to attack with the Bow for 3 DMG!");
}
else
{
Console.WriteLine("You don't have a Bow!");
}
break;
case ConsoleKey.D4:
Console.WriteLine("");
if (Items.iniLightstaff == true)
{
Console.WriteLine("You have chosen to attack with the Lightstaff for 4 DMG!");
}
else
{
Console.WriteLine("You don't have a Lightstaff!");
}
break;
case ConsoleKey.D5:
Console.WriteLine("");
Console.WriteLine("You can't attack with an Apple!");
break;
case ConsoleKey.D6:
Console.WriteLine("");
Console.WriteLine("You can't attack with a Golden Key!");
break;
case ConsoleKey.D7:
Console.WriteLine("");
Console.WriteLine("You can't attack with a Steak!");
break;
}
C# supports labels in code, however it is not recommended due to the fact that it violates many coding best practices, but I guess there is always an exception to any rule.
class Program
{
static void Main(string[] args)
{
Start:
Console.WriteLine("Start Here... Press any key");
var key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.A:
goto MyLabel;
case ConsoleKey.B:
goto MyLabel2;
case ConsoleKey.C:
goto MyLabel3;
default:
Console.WriteLine("Bad Choice");
goto Start;
}
MyLabel:
Console.WriteLine("MyLabel: A");
goto Start;
MyLabel2:
Console.WriteLine("MyLabel: B");
goto Start;
MyLabel3:
Console.WriteLine("MyLabel: C");
goto Start;
}
}
You can find more information here:
http://msdn.microsoft.com/en-us/library/d96yfwee.aspx
http://msdn.microsoft.com/en-us/library/13940fs2.aspx
you have a couple options, you can use a while loop
bool continue = true;
while(continue == true)// or you can simply type "while(continue)"
{
/* everything inside the `while` loop will be
repeated until `continue` is not `true`. */
}
you can also use methods
public static void doStuff()
{
// insert stuff here
}
and then you can call that from elsewhere in your class
if(x = 6)
{
doStuff(); //this line does the stuff
doStuff(); // this line does the stuff again.
}
One answer to this is to check that you have valid input in a loop like this:
while (true)
{
ConsoleKey i = Console.ReadKey()
if (i == ConsoleKey.D1 || ... ) //Check if it's equal to any valid key, you
//might be able to simplify it with <= and
//>= if valid keys are sequential.
break;
Console.WriteLine("You have entered an invalid key");
}
Alternatively, you can add a goto statement at the end of your switch block:
SwitchStatement: switch(input2.Key)
...
default:
Console.WriteLine("Invalid key pressed");
goto SwitchStatement;
break;
}

No need to press, when default is true (auto loop)

string tastetryk;
ConsoleKeyInfo tast;
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Blue;
Console.Clear();
do
{
Console.WriteLine("Menu");
Console.WriteLine(" ");
Console.WriteLine("Tryk en tast for at vælge funktion");
Console.WriteLine(" ");
Console.WriteLine("I - Beregn strøm");
Console.WriteLine("U - Spænding");
Console.WriteLine("R - Modstand");
Console.WriteLine(" ");
Console.WriteLine("(Esc) for at slutte ");
tast = Console.ReadKey();
tastetryk = tast.Key.ToString();
Console.Clear();
switch(tastetryk)
{
case "I":
Console.WriteLine("du har tastet I");
Console.Write("Tast Q for at komme tilbage");
tast = Console.ReadKey();
break;
case "U":
Console.WriteLine("du har tastet U");
Console.Write("Tast Q for at komme tilbage");
tast = Console.ReadKey();
break;
case "R":
Console.WriteLine("du har tastet R");
Console.Write("Tast Q for at komme tilbage");
tast = Console.ReadKey();
break;
default:
Console.WriteLine("forkert tast");
Thread.Sleep(1000);
Console.Clear();
break;
}
}
while (tast.Key == ConsoleKey.Q);
I made this code for a Menu, when i press I, U or R, one of the case will come true, when you press Q it will return to main menu. My problem is when default is true, i want it to loop to main menu without any need to press Q, I tried with tast = Consolekey.Q
Sorry for my really bad english
Clearly, you cannot break from the loop since the break breaks from the switch statement, as you've surely noticed.
Two simple solutions :
First, add a boolean flag indicating you should exit the loop, adding a new condition in the while statement.
bool bExit = false;
do
{
switch
{
/*
code here
*/
default:
bExit = true;
//etc.
}
}
while(tast.Key == ConsoleKey.Q || !bExit)
Now, I know thid could be considered pure evil but... have you considered using a goto?
do
{
switch
{
/*
code here
*/
default:
goto outOfLoop;
}
}
while(tast.Key == ConsoleKey.Q)
outOfLoop:
// etc.
I believe the second solution is actually cleaner but people could react violently to goto statements.

How can I loop a case switch statement if an invalid value is chosen i.e the default

Here is an example where a menu of values is available. i would like to have it loop back to the start if none of the options are chosen.
static void Main(string[] args)
{
Console.WriteLine("1 : Option 1");
Console.WriteLine("2 : Option 2");
Console.WriteLine("3 : Option 3");
Console.WriteLine("4 : Option 4");
Console.WriteLine("5 : Option 5");
Console.Write("Please enter your option choice: ");
string choice = Console.ReadLine();
int intChoice = int.Parse(choice);
switch (intChoice)
{
case 1:
Console.WriteLine("you chose 1");
break;
case 2:
Console.WriteLine("you chose 2");
break;
case 3:
Console.WriteLine("you chose 3");
break;
case 4:
Console.WriteLine("you chose 4");
break;
case 5:
Console.WriteLine("you chose 5");
break;
}
}
I've tried to do it through using classes and method, but i just got really confused.
thank you in advance for any help.
Wrap the whole thing in a do-while block:
bool isValid = true;
do
{
isValid = true;
// Write to console
// read from console
switch(intChoice)
{
// Place some cases here.
default:
Console.WriteLine("Invalid Choice")
isValid = false;
}
}
while(!isValid);
Use a boolean value as a flipswitch that tell the while loop to continue running or not. Here's a small example:
bool stillRunning = true;
while (stillRunning)
{
Console.WriteLine("Enter a number.");
string input = Console.ReadLine();
int key = Convert.ToInt32(input);
switch (key)
{
case 1:
// Do something.
stillRunning = false;
break;
case 2:
// Do something.
stillRunning = false;
break;
default:
Console.WriteLine("No key selected.");
break;
}
}
you can use default
switch (intChoice)
{
case 1:
Console.WriteLine("you chose 1");
break;
case 2:
Console.WriteLine("you chose 2");
break;
.......
default:
//your logic here
break;
}
it is your choice after that how you like to do it. you can use a while and a Boolean value like this:
static void Main(string[] args)
{
Console.WriteLine("1 : Option 1");
Console.WriteLine("2 : Option 2");
Console.WriteLine("3 : Option 3");
Console.WriteLine("4 : Option 4");
Console.WriteLine("5 : Option 5");
Console.Write("Please enter your option choice: ");
bool correct = true;
while (correct)
{
string choice = Console.ReadLine();
int intChoice = int.Parse(choice);
switch (intChoice)
{
case 1:
Console.WriteLine("you chose 1");
break;
case 2:
Console.WriteLine("you chose 2");
break;
case 3:
Console.WriteLine("you chose 3");
break;
case 4:
Console.WriteLine("you chose 4");
break;
case 5:
Console.WriteLine("you chose 5");
break;
default:
correct = false;
break;
}
}
}
Thus you need only one number, it's better to use GetKey method, then reading string value from console and then parsing it to int:
DisplayOptions();
bool choiceDone;
do
{
choiceDone = true;
switch(GetChoice())
{
case ConsoleKey.D1:
Console.WriteLine("you chose 1");
break;
case ConsoleKey.D2:
Console.WriteLine("you chose 2");
break;
// etc
default:
choiceDone = false;
break;
}
} while(!choiceDone);
Also I have extracted several methods, to make code more clean:
private ConsoleKey GetChoice()
{
Console.Write("Please enter your option choice: ");
return Console.ReadKey().Key;
}
private void DisplayOptions()
{
Console.Clear();
Console.WriteLine("1 : Option 1");
Console.WriteLine("2 : Option 2");
Console.WriteLine("3 : Option 3");
Console.WriteLine("4 : Option 4");
Console.WriteLine("5 : Option 5");
}
public void GetInput()
{
int inputValue = 0;
bool isValidInput = false;
List<int> validEntries = new List<int> { 1,2,3, 42, 55, 69};
while (!isValidInput)
isValidInput = int.TryParse(Console.ReadLine(), out inputValue) && validEntries.Contains(inputValue);
switch (inputValue)
{
case 1:
{
// something
break;
}
case 2:
{
// something else
break;
}
default:
{
//yet something else
break;
}
}
}
Edit: Added explicit value check instead of accepting any integer.
The most obvious solution seems to be:
bool loop = true;
while (loop)
{
loop = false;
switch (Console.ReadLine())
{
case "1":
Console.WriteLine("you chose 1");
break;
case "2":
Console.WriteLine("you chose 2");
break;
case "3":
Console.WriteLine("you chose 3");
break;
case "4":
Console.WriteLine("you chose 4");
break;
case "5":
Console.WriteLine("you chose 5");
break;
default:
loop = true;
break;
}
}
There could be a better way to do this though.

Console.ReadLine() alternative

I have the following console application:
private static bool run = false;
static void Main(string[] args)
{
int choice = 0;
while (!run)
{
Console.WriteLine("\n\t\t Press '1', '2' or '3' to continue");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
{
Console.Clear();
Console.WriteLine("\n\t\t you pressed 1");
}
case 2:
{
Console.Clear();
Console.WriteLine("\n\t\t you pressed 2");
}
case 3:
{
Console.Clear();
Console.WriteLine("\n\t\t you pressed 3");
}
default:
{
Console.Clear();
Console.WriteLine("\n\t\t Invalid key");
break;
}
}
}
Console.ReadLine();
}
However, with this code:
choice = int.Parse(Console.ReadLine());
I wish to have it so that when the user pressed the 1 key or 2 or 3, the appropriate code is executed straight away, as opposed to having to press the enter key once you've pressed the desired key. What are some alternatives?
Any help/guidance/tips is greatly appreciated,
Thanks
How about ReadKey then?

Categories

Resources