I have searched stackoverflow and haven't found anything that answers my question. Unfortunately it is not an easy question to word as a search query.
I'm using c# and I have a menu that asks the user to pick an option from 1 - 4. I am validation that the value picked is an integer, but my code breaks whenever I enter a letter or symbol. How do I add the validation for this to? My code currently is as follows.
static void Main(string[] args)
{
DirectoryInfo folderInfo = new DirectoryInfo("C:\\Windows");
FileInfo[] files = folderInfo.GetFiles();
int mainMenuChoice=0;
while ( mainMenuChoice != 1 || mainMenuChoice!= 2 || mainMenuChoice!= 3 || mainMenuChoice!= 4)
{
Console.WriteLine("What would you like to do?");
Console.WriteLine("1. Full File Listing.");
Console.WriteLine("2. Filtered File Listing.");
Console.WriteLine("3. FolderStatistics.");
Console.WriteLine("4. Quit.");
mainMenuChoice = int.Parse(Console.ReadLine());
if (mainMenuChoice == 1)
{
Option1();
}
if (mainMenuChoice == 2)
{
Option2();
}
if (mainMenuChoice == 3)
{
Option3();
}
if (mainMenuChoice == 4)
{
}
else
{
Console.WriteLine("you didnt enter a valid input! try again.");
}
}
Change the reading from the command line to
if(Int32.TryParse(Console.ReadLine(), out mainMenuChoice))
{
if (mainMenuChoice == 1)
Option1();
else if (mainMenuChoice == 2)
Option2();
else if (mainMenuChoice == 3)
Option3();
else if (mainMenuChoice == 4)
Option4();
else
Console.WriteLine("you didnt enter a valid input! try again.");
}
else
{
Console.WriteLine("you didnt enter a valid input! try again.");
}
and repeat the warning message for your user in the else part of the TryParse if.
Int32.TryParse return false when the characters on the command line cannot be converted to an integer and assigned to the out parameter mainMenuChoice.
Use int.TryParse instead:
if (!int.TryParse(Console.ReadLine(), out mainMenuChoice))
{
Console.WriteLine("That's not a number!");
}
...
But in fact, you're never actually using the input as a number, so there's no real need to parse it. You could just leave it as a string:
bool retry;
do
{
retry = false;
Console.WriteLine("What would you like to do?");
Console.WriteLine("1. Full File Listing.");
Console.WriteLine("2. Filtered File Listing.");
Console.WriteLine("3. FolderStatistics.");
Console.WriteLine("4. Quit.");
string mainMenuChoice = Console.ReadLine();
switch(mainMenuChoice)
{
case "1":
Option1();
break;
case "2":
Option2();
break;
case "3":
Option3();
break;
case "4":
break;
default:
Console.WriteLine("You didn't enter a valid input! Try again.");
retry = true;
break;
}
} while(retry);
Also, although this is pretty clear and easy to ready, you don't actually need the retry variable. Although it's a lot less obvious how this works (and I would probably avoid it for that reason), you can structure your loop like this:
do
{
Console.WriteLine("What would you like to do?");
Console.WriteLine("1. Full File Listing.");
Console.WriteLine("2. Filtered File Listing.");
Console.WriteLine("3. FolderStatistics.");
Console.WriteLine("4. Quit.");
string mainMenuChoice = Console.ReadLine();
switch(mainMenuChoice)
{
// same as above
default:
Console.WriteLine("You didn't enter a valid input! Try again.");
continue; // goes back to beginning of the loop
}
break; // exits the loop
} while(true);
while(true)
{
int menuChoice;
string userInput = Console.Readline();
if(Int32.TryParse(userInput, out menuChoice))
{
if(menuChoice >= 1 && menuChoice <= 4)
RunCommand(menuChoice);
else
Console.WriteLine("Enter a number between 1-4");
}
else
Console.WriteLine("A number between 1-4 is required!");
}
Use the TryParse method on Int (details here).
For example:
int menuChoice;
if(!int.TryParse(Console.Readline(),out menuChoice){
Console.WriteLine("The menu choice you made was invalid.");
} else {
//do the rest of your code here
}
Related
I'm a complete newbie when it comes to C#, and I'm sure this has a very simple answer:
I've written a super simple piece of code to enable a user to pop in a number and receive the square of that number back out. I've also enabled the user to decide whether they want to play or not, with Yes, No, or 'else' triggering different outcomes.
The 'Yes' input works just fine, with the program working as expected. However, the 'No' or 'else' response seems to require the user to enter a response a second time before triggering the outcome properly.
I can't see why it would be looking for a response twice in a row, so if you can offer any help I'd really appreciate it.
Here's the code I'm using:
namespace Playground
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("If you enter a number, I'll report back the number squared. Would you like to play? Enter Yes or No");
int x = 100;
while (x == 100)
{
if (Console.ReadLine() == "Yes")
{
Console.WriteLine("Great! Enter a number");
int initial = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(initial * initial);
Console.WriteLine("Would you like to try again?");
}
else if(Console.ReadLine() == "No")
{
Console.WriteLine("Ok, goodbye! Press any key to Exit");
Console.ReadLine();
Environment.Exit(0);
}
else
{
Console.WriteLine("Sorry, I didn't understand that. Please enter Yes or No");
}
}
}
}
}
When running into the first if the condition run the function Console.ReadLine() so you have to write the answer. This is going to happen also in the else if (Console.ReadLine() == "No").
What you have to do is save the user input only once and decide what to do from that answer.
The code is:
int x = 100;
while (x == 100)
{
string answer = Console.ReadLine();
if (answer == "Yes")
{
Console.WriteLine("Great! Enter a number");
int initial = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(initial * initial);
Console.WriteLine("Would you like to try again?");
}
else if(answer == "No")
{
Console.WriteLine("Ok, goodbye! Press any key to Exit");
Console.ReadLine();
Environment.Exit(0);
}
else
{
Console.WriteLine("Sorry, I didn't understand that. Please enter Yes or No");
}
}
You can also use the switch statement:
int x = 100;
while (x == 100){
string answer = Console.ReadLine();
switch (answer){
case "Yes":
Console.WriteLine("Great! Enter a number");
int initial = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(initial * initial);
Console.WriteLine("Would you like to try again?");
break;
case "No":
Console.WriteLine("Ok, goodbye! Press any key to Exit");
Console.ReadLine();
Environment.Exit(0);
break;
default:
Console.WriteLine("Sorry, I didn't understand that. Please enter Yes or No");
break;
}
}
I'm trying to learn C# and wanted to try making a simple program from scratch that asks the user to enter a number between 1-3, every number yields a lottery win and writing "exit" is supposed to exit the program. When one number is answered the user is supposed to be prompted to answer again until choosing to exit. No matter what I do when trying to combine a while loop and if statements I get errors or just infinite loops that won't stop. Probably some simple syntax misunderstanding.. Any help would be greatly appreciated.
This is my code so far:
static void Main(string[] args)
{
string userInput = "";
Console.Write("Pick a number between 1-3, type 'exit' to stop the program: ");
userInput = Console.ReadLine();
while (userInput != "exit")
if (userInput == "1")
{
Console.WriteLine("You won a car");
}
else if (userInput == "2")
{
Console.WriteLine("You won a boat");
}
else if (userInput == "3")
{
Console.WriteLine("Sorry, no luck this time. Try again");
}
else if (userInput == "exit")
{
Console.WriteLine("Exiting...");
break
}
else
{
Console.WriteLine("The number has to be between 1-3, try again.");
}
Console.ReadLine()
}
}
}
}
This should work
static void Main(string[] args)
{
string userInput = "";
Console.Write("Pick a number between 1-3, type 'exit' to stop the program: ");
userInput = Console.ReadLine();
while (userInput != "exit")
{
if (userInput == "1")
{
Console.WriteLine("You won a car");
}
else if (userInput == "2")
{
Console.WriteLine("You won a boat");
}
else if (userInput == "3")
{
Console.WriteLine("Sorry, no luck this time. Try again");
}
else if (userInput == "exit")
{
Console.WriteLine("Exiting...");
break
}
else
{
Console.WriteLine("The number has to be between 1-3, try again.");
}
userInput = Console.ReadLine()
}
}
}
The value of userInput is never updated in the loop, which means that each time the loop runs, the value stays the same.
A solution is to move the prompt and the reading into the start of the loop.
To add to Zayenz's answer, this is the key to all infinite loops; the circumstance evaluated that decides whether or not to begin the loop is always true. If you ever have this problem again, you just need to look at the code to make sure that whatever should break you out of the loop actually changes whatever criteria it needs to in order to make the condition false;
I am supposed to use only a sentinel while loop for an assignment. The user is meant to enter a department code, and for each department code its supposed to intake a mark and then at the end when the while loop is exited it calculates the average. My question is can I break out an an If statement inside a while loop without breaking out of the while loop itself? And once Q is pressed exit out of the program?
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or " +
"‘m’ for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadKey().KeyChar;
while (char.ToUpper(deptCode) != 'Q')
{
if (char.ToUpper(deptCode) == 'C')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
computerScienceMark = Convert.ToInt32(Console.ReadLine());
break;
}
else if (char.ToUpper(deptCode) == 'B')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
businessMark = Convert.ToInt32(Console.ReadLine());
break;
}
else if (char.ToUpper(deptCode) == 'M')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
mathMark = Convert.ToInt32(Console.ReadLine());
break;
}
if (char.ToUpper(deptCode) == 'Q')
{
Console.WriteLine("you entered Q to quit");
Environment.Exit(0);
}
else
{
Console.WriteLine("\nYou entered a wrong input please try again");
break;
}
}
You could put the whole request for a department code inside a while.
That way the users will be asked for a new code until they enter 'Q', like this
while (true)
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or ‘m’ for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadLine()[0];
if (char.ToUpper(deptCode) == 'Q')
break;
if (char.ToUpper(deptCode) == 'C')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
computerScienceMark = Convert.ToInt32(Console.ReadLine());
}
else if (char.ToUpper(deptCode) == 'B')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
businessMark = Convert.ToInt32(Console.ReadLine());
}
else if (char.ToUpper(deptCode) == 'M')
{
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
mathMark = Convert.ToInt32(Console.ReadLine());
}
else
{
Console.WriteLine("\nYou entered a wrong input please try again");
}
}
https://www.jdoodle.com/iembed/v0/8Wi
You want two loops. One outer one to get the department codes, and one inner one to get the mark. Something along the lines of:
static void Main(string[] args)
{
while (true) // outer loop
{
string department;
Console.WriteLine("Enter department code:");
department = Console.ReadLine().ToUpper();
if (department == "Q")
{
break; // end the outer loop
}
else if (department == "C"
|| department == "B"
|| department == "M")
{
while (true) // inner loop
{
int mark;
Console.WriteLine("Enter mark:");
if (int.TryParse(Console.ReadLine(), out mark)
&& mark >= 0
&& mark <= 100))
{
break; // end the inner loop;
}
else
{
Console.WriteLine("Invalid mark. Try again.");
}
}
}
else
{
Console.WriteLine("Invalid department code. Try again.");
}
}
}
To end the outer loop check if department was "Q" and break. For the inner one break when the mark was correctly entered. You can use int.TryParse() to check if the string entered really represents an integer for that check.
bool check = false;
while (check == false)
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘M’ or ‘m’ " +
"for Math, ‘B’ or ‘b’ for Business Admin, or enter ‘Q’ or ‘q’ to quit => C");
char deptCode = Console.ReadLine()[0];
if (char.ToUpper(deptCode) == 'Q')
{
check = true;
}
Console.WriteLine("\nEnter the mark (>= 0 or <= 100)");
switch (char.ToUpper(deptCode))
{
case 'C':
computerScienceMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
case 'B':
businessMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
case 'M':
mathMark = Convert.ToInt32(Console.ReadLine());
check = true;
break;
default:
Console.WriteLine("\nYou entered a wrong input please try again");
break;
}
}
To a consenus it is bad programing form to use break, continue, goto and such. Don't let me tell you how to program, use whatever you like and be my guest. However, if you're a beginner and wanting to learn transferable skills it's genuinely regarded as sloppy to use break - this is because it can leave behind "un tided up" (for lack of a better expression) memory. I only mean when using break when in an iteration.
My soultion is very similar to Jack Lilhammers, although I prefer the switch statement here, it's a little neater. Furthermore, using an idividual variable for the while condition is a nice idea because it's a good habbit to get acustomed with when doing larger more complex while loops where u might find yourself stepping throught the code and having that variable allows you to nicely observe it's state throughout.
I am trying to make a small cinema program, setting if statements depending on the users age, and one age is 12 A, meaning I have to ask if they are accompanied by an adult
Console.WriteLine(" Enter the number of the film you wish to see :");
int selection = int.Parse(Console.ReadLine());
Console.WriteLine("Enter your age:");
int age = int.Parse(Console.ReadLine());
bool yes = true;
bool no = false;
with the first two options i
have, everything goes smoothly.
if (selection == 3)
{
if (age >= 12)
{
Console.WriteLine("You may enter");
}
else
{
{
Console.WriteLine("Are you accompanied by an adult? Answer yes or no" );
Console.ReadLine();
if (true)
{
Console.WriteLine("You may pass.");
}
else if (false)
{
Console.WriteLine("You are not allowed.");
...
Here, no matter what I input it will go through the first conditional and end there or it is unreachable code if I write Console.ReadLine(); on the else if statement.
Thanks in advance for any help.
Rather than evaluating true, or false which will always give the same answer you need to check what the user wrote back to you by storing it in a variable.
if (age >= 12)
{
Console.WriteLine("You may enter");
}
else
{
string response = null;
while(response != "yes" || response != "no"){
response = Console.ReadLine("Are you accompanied by an adult? Answer yes or no" );
}
if (response == "yes")
{
Console.WriteLine("You may pass.");
}
//Only other way to get here is if they answered, "no" so don't need to check response
else{
Console.WriteLine("You are not allowed.");
}
}
You should check not true or false constants, but actual user input, say bool accompanied:
if (selection == 3) {
if (age >= 12)
Console.WriteLine("You may enter")
else {
Console.WriteLine("Are you accompanied by an adult? Answer yes or no" );
// Trim() - let's be nice and allow user to leave leading/trailing spaces
string input = Console.ReadLine().Trim();
// accompanied if user's input "y" or "yes" (case insensitive)
bool accompanied = "yes".Equals(input, StringComparison.OrdinalIgnoreCase) ||
"y".Equals(input, StringComparison.OrdinalIgnoreCase);
if (accompanied)
Console.WriteLine("You may pass.");
else
Console.WriteLine("You are not allowed.");
}
}
You forgot to receive the value of the adult follow-up question.
Try this:
private static void Main(string[] args)
{
Console.WriteLine(" Enter the number of the film you wish to see :");
int selection = int.Parse(Console.ReadLine());
Console.WriteLine("Enter your age:");
int age = int.Parse(Console.ReadLine());
if (selection == 3)
{
if (age < 12)
{
Console.WriteLine("Are you accompanied by an adult? Answer yes or no");
string isAccompanied = Console.ReadLine();
if (isAccompanied.ToUpper().Equals("NO"))
{
Console.WriteLine("You are not allowed.");
return;
}
Console.WriteLine("You may pass.");
return;
}
Console.WriteLine("You may enter");
return;
}
}
if you want "yes/no", you should store it in a string variable, evaluate if condition according to this variable.
if (selection == 3)
{
if (age >= 12)
{
Console.WriteLine("You may enter");
}
else
{
{
Console.WriteLine("Are you accompanied by an adult? Answer yes or no" );
string res = Console.ReadLine();
if (res == "yes")
{
Console.WriteLine("You may pass.");
}
else if (res == "no")
{
Console.WriteLine("You are not allowed.");
You're reading the input, but not doing anything with it:
Console.ReadLine();
And you are trying to evaluate a hard-coded boolean literal which will never change:
if (true)
Instead, examine what's actually being input. For example:
var userInput = Console.ReadLine();
if (userInput.Equals("yes", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("You may pass.");
}
else
{
Console.WriteLine("You are not allowed.");
}
It looks like you are not storing or testing the answer to the question 'Are you accompanied by an adult?'. You need to store the answer from the readline method and test if the answer = yes or no.
IE: amend the top of your file to include a variable to check the age against:-
Console.WriteLine(" Enter the number of the film you wish to see :");
int selection = int.Parse(Console.ReadLine());
Console.WriteLine("Enter your age:");
int age = int.Parse(Console.ReadLine());
bool isUserOldEnough = false;
And then modify your code to something like:-
if (selection == 3)
{
if (age >= 12)
{
Console.WriteLine("You may enter");
}
else
{
Console.WriteLine("Are you accompanied by an adult? Answer yes or no" );
if (Console.ReadLine().ToLower() == "yes") isUserOldEnough = true;
if (isUserOldEnough == true)
{
Console.WriteLine("You may pass.");
}
else
{
Console.WriteLine("You are not allowed.");
}
}
}
I am fairly new to C# and currently building a simple ATM app. I am attempting to write code to return the user to the main menu according to his/her entry of the letter M. The break, continue, goto or return keywords do not seem to work in my scenario; perhaps I used them incorrectly. The statement directly below is where I would like to jump to.
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving");
I would like to jump from the line JUMP (below) within the else if statement nested within the switch statement into the section of code above. How can I achieve this? any help is appreciated...thanks!
switch (response)
{
case "C1":
Console.WriteLine("How much would you like to deposit to your checking account?");
string depositEntry = Console.ReadLine();
double checkingBalance = Convert.ToInt32(depositEntry) + currentCheckingBalance;
currentCheckingBalance += checkingBalance;
Console.WriteLine("Your current checking balance is " + checkingBalance + "\n (X) Exit, (M) Main Menu" );
string selection = Console.ReadLine().ToUpper();
if (selection == "X")
{
return;
}
else if (selection == "M")
{
***JUMP***
}
else
{
Console.WriteLine("Your entry was invalid");
}
break;
case "C2":
break;
case "W1":
Using a jump statement usually indicates the flow of logic is jumbled. I try to avoid any kind of jumps if necessary. The code below prints out a main menu and if the user types “x” the program will quit. If the user selects one of the other options, a message is simply printed out indicating what the user selected. After the user presses any key, the console clears and the main menu is re-displayed.
In the main menu, if the user does not type one of the selections, then the selection is ignored, the console is cleared, and the menu is reprinted. No error is displayed indicating invalid selections.
This does not require the user to type “m” to go back to the main menu. After a selection is made for Deposit/withdraw/… after the method is finished the code will automatically return to the main menu.
I am guessing this may be what you are looking for. Hope this helps.
static void Main(string[] args) {
string userInput = "";
while ((userInput = GetMainSelection()) != "x") {
switch (userInput) {
case "c1":
Console.WriteLine("C1 Deposit Checking method");
break;
case "c2":
Console.WriteLine("C2 Deposit Savings method");
break;
case "b1":
Console.WriteLine("B1 View Balance Checking method");
break;
case "b2":
Console.WriteLine("B2 View Balance Savings method");
break;
case "w1":
Console.WriteLine("W1 Withdraw Checking method");
break;
case "w2":
Console.WriteLine("W2 withdraw Savings method");
break;
}
Console.WriteLine("Press Any Key to continue"); // <-- show what method was just used
Console.ReadKey();
Console.Clear();
}
Console.Write("Press any key to exit the program");
Console.ReadKey();
}
private static string GetMainSelection() {
string userInput = "";
while (true) {
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving. (X) to EXit");
userInput = Console.ReadLine().ToLower();
if (userInput == "b1" || userInput == "b2" || userInput == "c1" || userInput == "c2" || userInput == "w1" || userInput == "w2" || userInput == "x") {
return userInput;
}
else {
Console.Clear();
}
}
}
Put the JUMP code in a function and return.
public void MainMenu() {
// Show the main menu
}
public void Response(string response) {
switch (response)
{
case "C1":
Console.WriteLine("How much would you like to deposit to your checking account?");
string depositEntry = Console.ReadLine();
double checkingBalance = Convert.ToInt32(depositEntry) + currentCheckingBalance;
currentCheckingBalance += checkingBalance;
Console.WriteLine("Your current checking balance is " + checkingBalance + "\n (X) Exit, (M) Main Menu" );
string selection = Console.ReadLine().ToUpper();
if (selection == "X")
{
return;
}
else if (selection == "M")
{
***JUMP***
MainMenu();
return;
}
else
{
Console.WriteLine("Your entry was invalid");
}
break;
case "C2":
break;
case "W1":
}
}
Similar to the already given answer, I suggest breaking this out. Here's an example:
The Main method:
static void Main(string[] args) {
string input = null;
do {
input = Console.ReadLine();
ParseInput(input);
} while (input != "X");
}
ParseInput:
static void ParseInput(string input) {
switch (input) {
case "X": //from Main(), this will close the app
return;
case "M":
MainMenu();
break;
case "C1":
ShowAccount("C1"); //move your deposit/withdraw logic into a method and call with the selected account
return;
//other accounts
default:
break; //error message?
}
}
and MainMenu:
static void MainMenu() {
Console.WriteLine("Select an option? \n VIEW BALANCE (B1) checking, (B2) saving \n DEPOSIT (C1) checking, (C2) saving \n WITHDRAW (W1) checking, (W2) saving");
}
This should let you read the input in a loop and the ParseInput function can handle your individual cases. You may also want to call MainMenu() at the start, so it shows from the beginning.
It works like this:
Get input from the user
Pass the input to ParseInput() which decides where to go next.
Any functions hit in ParseInput() will execute, writing to the console or asking for further input
Once that function returns, while (input != "X") evaluates. If input != "X", goto 1, else exit.
I suggest you use goto C# reference.
static void Main()
{
int x = 200, y = 4;
int count = 0;
string[,] array = new string[x, y];
// Initialize the array:
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
array[i, j] = (++count).ToString();
// Read input:
Console.Write("Enter the number to search for: ");
// Input a string:
string myNumber = Console.ReadLine();
// Search:
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
if (array[i, j].Equals(myNumber))
{
goto Found;
}
}
}
Console.WriteLine("The number {0} was not found.", myNumber);
goto Finish;
Found:
Console.WriteLine("The number {0} is found.", myNumber);
Finish:
Console.WriteLine("End of search.");
// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
Output for the Input 44 would be:
Enter the number to search for: 44
The number 44 is found.
End of search.
See here for the MSDN reference.