I am having trouble figuring out how to break out of a loop that contains a switch statement.
i need to press 0 twice to exit the console why?
how can i fix it to exit from the first time
public void Start()
{
int choice = 0;
bool trueNumber = false;
do
{
ShowMenu(); // display the menu
Console.Write("Your Choice : ");
trueNumber = int.TryParse(Console.ReadLine(), out choice);
if (!trueNumber)
Console.WriteLine("Your Choice must be an integer. Try again.");
switch (choice) // select the relevant function based on user input
{
case 1:
CalculateCelsiusToFahrenheit();
break;
case 2:
CalculateFahrenheitToCelsius();
break;
case 0:
return; // exit when i press 0
default:
Console.WriteLine("Invalid Option: Choose 0, 1, or 2 Thank you ");
break;
}
} while (choice != 0);
}
If you are running this from an IDE (like Visual Studio), the default behavior for console applications is to end with a "Press any key to continue." so it waits with the output displayed.
related answer: VS setting
Related
I'm a complete Newbie to the world of programming, yet I really wish to learn a lot as quick as possible and now came up to a problem that I can't find to solute just via researching and "learning- by doing" (Trying around).
Basically I'm trying to work on a small console- based TextAdventure in C Sharp (With VisualStudios) Now I came to a Case- Switch (Offering the User some Options to read and walk through), but I wish to add a Y/N Confirmation in case the User decides to take a different path. For now it's only for the starting point of the story:
Does the User want to go into "The Wilds", "The City", "The Farm". Something as simple as that just in addition: "Are you sure (Y/N)?" leading the No to return the given choices.
Thank you all in advance and stay healthy!
Menu mainMenu = new Menu(prompt, options);
int selectedIndex = mainMenu.Run();
switch (selectedIndex)
{
case 0:
EnterTheWorld();
break;
case 1:
VisitTheMemorial();
break;
case 2:
TakeYourLeave();
break;
default:
break;
}
}
private void TakeYourLeave()
{
WriteLine("\nYou are about to take your leave... Are you sure ? (Y/N)");
ReadKey();
Environment.Exit(0);
}
private void VisitTheMemorial()
{
Clear();
//FILLER//
WriteLine("You may proceed by the press of any button.");
ReadKey(true);
RunMainMenu();
}
private void EnterTheWorld()
{
string prompt = "Where would you like to start your journey?";
string[] options = { "The Slums", "The Wilds", "The City", "The Farm" };
Menu startMenu = new Menu(prompt, options);
int selectedIndex = startMenu.Run();
BackgroundColor = ConsoleColor.White;
switch (selectedIndex)
{
case 0:
ForegroundColor = ConsoleColor.Black;
WriteLine("\n ||Small Description||Are you sure to take this path? (Y/N)");
break;
case 1:
ForegroundColor = ConsoleColor.Green;
WriteLine("\n ||Small Description||Are you sure to take this path? (Y/N)");
break;
case 2:
ForegroundColor = ConsoleColor.Red;
WriteLine("\n ||Small Description||Are you sure to take this path? (Y/N)");
break;
case 3:
ForegroundColor = ConsoleColor.Yellow;
WriteLine("\n ||Small Description|| Are you sure to take this path? (Y/N)");
break;
}
In this case, you need to take care of a few things:
Make sure that the entire switch-statement logic is in a while-loop, as such:
while (True) {
int selectedIndex = mainMenu.Run();
switch (selectedIndex)
{
case 0:
EnterTheWorld();
break;
case 1:
VisitTheMemorial();
break;
case 2:
TakeYourLeave();
break;
default:
break;
}
}
Check with your function if the input given is "No", if such, then immeditely return so your function exits before any navigation
private void VisitTheMemorial()
{
userInput = readKeyFunction();
if (userInput == "no") {
return;
}}
Finally, if the user doesn't select no, just do nothing and let the function go on
It is best to handle the 'Are you sure?' inside the menu.Run(), and return a value to the selectedIndex after the confirmation. Also avoid using while loop at the main flow in this case.
Note: you have to think in a modular way. Consider your Menu class as a module which handles user choice. The main flow does not have to bother about the confirmation by the user, it just have to process the final result of the user.
Another suggestion: Use enums instead of integers wherever possible for multiple choices.
So I'm working on a Switch-Case menu for my program but I'm having multiple issues (I'm probably missing something real obvious here)
So first off I'm trying to implement a while loop to make it possible to return to the menu after executing any of the case methods. However when trying to implement a while loop it doesn't seem to recognise my bool variable for some reason.
Secondly I'm not quite sure how to make it so the user can return to the start menu after they've done what they want to do in the case they've chosen, this probably has a real easy solution, but I just can't find one.
[code]
private string[] säten = new string[24];
private int Antal_passagerare = 0;
public void Run()
{
bool continue = true;
while(continue)
{
string menu = (Console.ReadLine());
int tal = Convert.ToInt32(menu);
switch(tal)
{
case 1:
Add_passagerare;
break;
case 2:
break;
case 3:
break;
}
}
}
[/code]
Your problem is that your local variable name conflicts with the C# keyword (or statement) continue which controls the flow of a loop (e.g. for, foreach, while, etc). Another control flow keyword is break.
You must rename the local variable. But because of the flow control keywords you can drop the local variable (see below). Also use Int32.TryParse to avoid your program from crashing, if the user inputs a non numeric value. In this context you can see the statements continue and break at work:
// Start an infinite loop. Use the break statement to leave it.
while (true)
{
string userInput = Console.ReadLine();
// Quit if user pressed 'q' or 'Q'
if (userInput.Equals("Q", StringComparison.OrdinalIgnoreCase)
{
// Leave the infinite loop
break;
}
// Check if input is valid e.g. numeric.
// If not show message and ask for new input
if (!(int.TryParse(userInput, out int numericInput))
{
Console.WriteLine("Only numbers allowed. Press 'q' to exit.");
// Skip remaining loop and continue from the beginning (ask for input)
continue;
}
switch (numericInput)
{
case 1:
break;
case 2:
Add_passagerare();
break;
case 3:
break;
}
}
Total beginner here, literally started learning programming for the first time in my life yesterday, so please don't judge!
I'm trying to make a program that allows the user to enter the name and score of videogames, then show these scores upon request. I'm trying to make a menu. I noticed the program would crash if the user presses enter without entering any number, and I wanted to avoid that, but I'm stuck. If I press enter it doesn't crash. However, if I enter 1 or 2, the menu keeps going anyways, and if I press enter without entering anything after that, then it crashes? I'm lost.
namespace videogaems
{
class Program
{
static void Main(string[] args)
{
menu();
}
static void menu()
{
int option = 0;
Console.WriteLine("Select what you want to do: ");
Console.WriteLine("1- add game");
Console.WriteLine("2- show game rating");
bool tryAgain = true;
while (tryAgain)
{
try
{
while (option != 1 || option != 2)
{
option = Convert.ToInt32(Console.ReadLine());
tryAgain = false;
}
}
catch (FormatException)
{
option = 0;
}
}
}
Convert.ToInt32(Console.ReadLine()) will throw an exception if the string cannot be converted to an integer. Instead, you should use int.TryParse, which takes in a string and an out parameter that gets set to the converted value (if successful). It returns a bool which indicates if it was successful or not.
For example, the following code will loop as long as int.TryParse fails, and when it succeeds, userInput will contain the converted number:
int userInput;
while (!int.TryParse(Console.ReadLine(), out userInput))
{
Console.WriteLine("Please enter a whole number");
}
Another option, however, is to simply use Console.ReadKey(), which returns a ConsoleKeyInfo object that represents the key that the user pressed. Then we can just check the value of the key character (and ignore any keys that are invalid).
For example:
static void Menu()
{
bool exit = false;
while (!exit)
{
Console.Clear();
Console.WriteLine("Select what you want to do: ");
Console.WriteLine(" 1: Add a game");
Console.WriteLine(" 2: Show game rating");
Console.WriteLine(" 3: Exit");
ConsoleKeyInfo userInput = Console.ReadKey();
Console.WriteLine();
switch (userInput.KeyChar)
{
case '1':
// Code to add a game goes here (call AddGame() method, for example)
Console.Clear();
Console.WriteLine("Add a game was selected");
Console.WriteLine("Press any key to return to menu");
Console.ReadKey();
break;
case '2':
// Code to show a game rating goes here (call ShowRating(), for example)
Console.Clear();
Console.WriteLine("Show game rating was selected");
Console.WriteLine("Press any key to return to menu");
Console.ReadKey();
break;
case '3':
// Exit the menu
exit = true;
break;
}
}
}
What I want to do is to to change the console depending on what the user has pressed.
So I have a console with three options like this:
> Option 1
Option 2
Option 3
Basically, if the user presses the down arrow, the console becomes like this:
Option 1
> Option 2
Option 3
And if the user presses the up arrow, the console goes back to it's initial state.
I know how to read the user's input with Console.ReadKey(), but I don't know how to modify output that is already written.
One last thing is that when the user presses enter, the console does not create a new line, but chooses one of the options and calls a delegate.
This isn't too difficult to achieve using Console.ReadKey and some variables to hold the state of the selected option.
The following code is a very quick and lazy implementation of what you are looking for. Take the time to rewrite it yourself properly - this is to give you an idea of how you could achieve what you are looking for.
static void Main(string[] args)
{
bool IsRunning = true;
int Selected = 1;
while (IsRunning)
{
ConsoleKeyInfo NextKey = new ConsoleKeyInfo();
if (Selected < 1)
Selected = 3;
else if (Selected > 3)
Selected = 1;
Console.Clear();
if (Selected == 1)
Console.Write("> ");
Console.WriteLine("Option 1");
Console.WriteLine();
if (Selected == 2)
Console.Write("> ");
Console.WriteLine("Option 2");
Console.WriteLine();
if (Selected == 3)
Console.Write("> ");
Console.WriteLine("Option 3");
Console.WriteLine();
Console.Write("Choose an option (Q to Quit): ");
while (!(NextKey.Key == ConsoleKey.DownArrow ||
NextKey.Key == ConsoleKey.UpArrow ||
NextKey.Key == ConsoleKey.Q ||
(NextKey.KeyChar >= '1' &&
NextKey.KeyChar <= '3')))
{
NextKey = Console.ReadKey();
}
switch (NextKey.Key)
{
case ConsoleKey.D1:
// Do something
break;
case ConsoleKey.D2:
// Do something
break;
case ConsoleKey.D3:
// Do something
break;
case ConsoleKey.DownArrow:
Selected++;
break;
case ConsoleKey.UpArrow:
Selected--;
break;
case ConsoleKey.Q:
IsRunning = false;
break;
}
}
}
The code will loop whilst the 'Q' key has not been pushed to quit the application.
Pushing the down or up arrow will rotate through the options available.
Upon pushing 1, 2, or 3, you will cause the // Do something lines inside the switch statement to be run. You should here call whatever functionality exists for each of the options.
In order to update the 'menu' with the chosen option, the console output is cleared and then re-output. The correct option is identified via the Selected variable.
There are several other ways to implement the above, some much tidier. I wanted to give you an idea of where to start. I am not saying that this is the best or most tidy solution.
EDIT
A thought occurs - you wanted to use Enter to select the option.
I've modified the code a little to provide that functionality:
while (!(NextKey.Key == ConsoleKey.DownArrow ||
NextKey.Key == ConsoleKey.UpArrow ||
NextKey.Key == ConsoleKey.Q ||
NextKey.Key == ConsoleKey.Enter))
{
NextKey = Console.ReadKey();
}
switch (NextKey.Key)
{
case ConsoleKey.Enter:
// Do something depending on Selected option
switch (Selected)
{
case 1:
// Do something
break;
case 2:
// Do something
break;
case 3:
// Do something
break;
}
break;
case ConsoleKey.DownArrow:
...
Here's a similar approach with a little less code, which hides the cursor and shows our own custom cursor that indicates the selected menu item.
The method takes in a menu header, a list of options for the user to select from, and a cursor character. It prints out the header and an underline, and then each option with 3 spaces before each one. Then we move the cursor to the first option (row index 3 since the header is 0, underline is 1, and blank space is 2), second character, and write a backspace character followed by our cursor (the backspace erases the first character so we can write a new one).
As the user presses keys, we only handle the up and down arrows and the enter key. By passing true to Console.ReadKey(), the user input is "thrown away" and not displayed on the window. This allows us to switch on only the keys we care about.
When they press an arrow key we move the cursor to the second column in the current row, print a backspace and then a space (to erase the old cursor), then move up or down one row, and from the second column we print a backspace and then our cursor character.
When the user presses Enter, we enable the console cursor again and return the row that the cursor was on to indicate which item was selected at that time:
private static int GetMenuChoice(string header, List<string> options, char cursor = '>')
{
// Clear console and hide cursor
Console.Clear();
Console.CursorVisible = false;
// Write our header with an underline
Console.WriteLine(" " + header);
Console.WriteLine(" " + new string('-', header.Length));
Console.WriteLine();
// Write out each option with spaces before it
options.ForEach(option => Console.WriteLine($" {option}"));
// Move to the first option and, from the second character,
// write a backspace and then the cursor symbol
Console.SetCursorPosition(1, 3);
Console.Write($"\b{cursor}");
// Move cursor when user presses arrow keys, and get selection when they press enter
while (true)
{
// Pass 'true' to ReadKey so the input is not written
var input = Console.ReadKey(true);
switch (input.Key)
{
case ConsoleKey.UpArrow:
if (Console.CursorTop > 3)
{
Console.CursorLeft = 1;
Console.Write("\b ");
Console.SetCursorPosition(1, Console.CursorTop - 1);
Console.Write($"\b{cursor}");
}
break;
case ConsoleKey.DownArrow:
if (Console.CursorTop < options.Count + 2)
{
Console.CursorLeft = 1;
Console.Write("\b ");
Console.SetCursorPosition(1, Console.CursorTop + 1);
Console.Write($"\b{cursor}");
}
break;
case ConsoleKey.Enter:
var selection = Console.CursorTop - 3;
Console.CursorVisible = true;
Console.SetCursorPosition(0, options.Count + 4);
return selection;
}
}
}
This can be tested out with a sample ATM menu:
private static void Main()
{
var options = new List<string>
{
"Open a new account",
"Deposit Money",
"Withdraw money",
"Check balance",
"Exit"
};
var selectedItem = GetMenuChoice("ATM Machine", options);
Console.WriteLine($"You selected option: '{options[selectedItem]}'");
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
I could loop the switch statement only twice. After the second time the console closes no matter what option I have chosen from the switch case. How I should modify my code so that the user could continue to loop the switch case until they decide to stop?
Thank you for your suggestions.
int userChoice = 0;
Console.WriteLine("This is an application. It has many different modes.");
Console.WriteLine("You can activate the mode of the application, which can be inserting, retrieving, printing, saving or uploading.");
Console.WriteLine("Type 'I' to insert, 'R' to retrieve, 'P' to print, 'S' to save, 'U' to upload the data, or 'T' to terminate the application.");
string mode = Console.ReadLine();
switch (mode)
{
case "I":
Console.WriteLine("You have chosen to insert the data.");
break;
case "R":
Console.WriteLine("You have chosen to retrieve the data.");
break;
case "P":
Console.WriteLine("You have chosen to print the data.");
break;
case "S":
Console.WriteLine("You have chosen to save the data.");
break;
case "U":
Console.WriteLine("You have chosen to upload the data.");
break;
case "T":
Console.WriteLine("You have chosen to terminate the application.");
return;
}
// Two modes, quit option
if (mode == "I" || mode == "R")
{
Console.WriteLine("The application will stay in the insert or retrieve modes. Press 'Q' to exit to the modes to return to the main menu.");
}
while (userChoice != 0)
{
Console.WriteLine("Please choose one of the modes {0}.", userChoice);
userChoice++;
}
Console.WriteLine("Type 'I' to insert, 'R' to retrieve, 'P' to print, 'S' to save, 'U' to upload the data, or 'T' to terminate the application.");
Console.ReadLine();
It looks like you want something like this (pseudocode)
bool finished
while(!finished) //Loop until they make a choice
{
Console.WriteLine("Type 'I' to insert, 'R' to retrieve, 'P' to print, 'S' to save, 'U' to upload the data, or 'T' to terminate the application.");
var input = Console.Readline();
switch(input)
{
//Respond to the input. If the input should cause the application
//to terminate, set finished = true
}
if(!finished)
{
//Indicate that the user can make more choices
}
}
// The loop exits when finished = true, and the program ends