Input is not being taken - c#

Understanding:
A Programm for someone that just started going to the Gym. (I'm trying
to learn c#)
First, the User fills out his Name, Age, Gender, Weight Height.
Then The user Picks a Goal.
To get a better understanding, something along these lines happens. (after the steps above)
if (Goal.GoalStatusGainWeight == true && Console.ReadLine() == "y")
{
Console.Clear();
InitFiveByFive();
//Caluclate Calories based on Gender and Goal
GainWeight.ShowFoodsToGainWeight();
Nutrition.CalcuateCalories();
ExitToMenu();
}
This is where my Problem is:
private static void ExitToMenu()
{
Console.WriteLine("PRESS ESC To Return to the MENU");
var input = Console.ReadKey();
if (input.Key == ConsoleKey.Escape)
{
Console.Clear();
InitMenu();
}
}
Problem is when I get back to the Menu. And Input something again.
do
{
var userInput = Console.ReadKey();
try
{
switch (userInput.Key)
{
case ConsoleKey.D1:
Console.Clear();
InitUser();
InitGoals();
Stats.ShowStats = true;
Menu.ShowMenu = false;
break;
case ConsoleKey.D2:
Console.Clear();
Menu.Disclamer();
Menu.ShowMenu = true;
Menu.ShowDiscalmer = true;
break;
case ConsoleKey.D3:
Console.Clear();
Menu.MadeBy();
break;
default:
Console.Clear();
InitMenu();
break;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
if (Menu.ShowMenu == false)
{
Menu.MenuOnOff = false;
}
} while (Menu.MenuOnOff == true);
It will not take the input again. And I'm not sure how to handle the situation.
After the User Exists the 'Workout Plan' back to the Menu, and I try to Press 1 again, (case ConsoleKey.D1:) my Console App just closes.
I hope I got everything that you need to help me if there's something missing please let me know.
Thank you.

Related

How do I stop the Console.ReadLine() command triggering multiple times in my loop?

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;
}
}

How do I repeat a question in a switch case

I'm trying to make a question repeat if the input isn't right. Here's the code:
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
Boolean input = true;
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
break;
case "bob":
Console.WriteLine("you chose a bob");
break;
}
How do I make it if it isn't one of the two answers it reasks the question?
Use the default case.
If none of the cases in a switch statement match, the default case runs.
Here's an example.
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
switch (userInput)
{
case "joe":
// ...
break;
case "bob":
// ...
break;
default:
// This runs if userInput is neither "joe" nor "bob"
}
Then you can make a method that writes choose a name to the console, takes the user's input, and runs the switch statement - and the default case would call the same method.
void GetName()
{
// Write "choose a name" to the console
// Take the user's input
switch (userInput)
{
case "joe":
// ...
break;
case "bob":
// ...
break;
default:
GetName();
return;
}
}
You need a loop (either while or do-while) to repeat the iteration but not a switch-case.
While switch-case is used to control the flag (isCorrectInput) that stops the loop.
bool isCorrectInput = false;
do
{
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
isCorrectInput = true;
break;
case "bob":
Console.WriteLine("you chose a bob");
isCorrectInput = true;
break;
}
} while (!isCorrectInput);
Reference
Iteration statement
You should use a bool variable, that will determine whether you need to repeat the logic or not. Combine it with a loop and you get this:
bool keepAsking = true;
while (keepAsking)
{
Console.WriteLine("choose a name");
string userInput = Console.ReadLine();
Boolean input = true;
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
keepAsking = false;
break;
case "bob":
Console.WriteLine("you chose a bob");
keepAsking= false;
break;
}
}
You can try something like this. BUt you need to slightly change your code.
class XYZ
{
static void Main(string[] args)
{
GetData()
}
}
static void GetData()
{
string userInput = Console.ReadLine();
checkcondition(userInput);
}
static void checkcondition(userInput)
{
switch (userInput)
{
case "joe":
Console.WriteLine("you chose a joe");
break;
case "bob":
Console.WriteLine("you chose a bob");
break;
default:
GetData();
break;
}
}
You can also achieve the same results using a smaller code but with a while loop instead of switch statement
while(true){
Console.Write("Choose a Name: ");
var name = Console.ReadLine().ToLower();
if(name == "joe" || name == "bob"){
Console.WriteLine("You chose a " + name + "!");
break;
}else{
Console.WriteLine("Invalid Selection, Try Again");
}
}

Case Switch with a loop

I am not understanding what is going on in my case statement to determine if I want to redo the users input. Should I make another loop outside of my while loop? I attempted such and my case statement becomes unreachable code. Maybe I am not understanding case-switch statements.
class Program
{
static void Main(string[] args)
{
string _a = "";
constructor con = new constructor();
Console.WriteLine("Enter enter exit to end the program...");
Console.WriteLine("Enter C for constructor, M for method, A for an array...");
Console.WriteLine("Please reference source code to have full details and understanding...");
bool control = true;
while (control)
{
_a = Console.ReadLine();
switch (_a.ToUpper())
{
case "EXIT":
Console.WriteLine("Thank you for using AJ's program...");
control = false;
break;
case "C":
Console.WriteLine(con.a);
Console.WriteLine("Would you like to test another scenario?");
Console.ReadLine();
if (_a.ToUpper() == "Y")
{
Console.ReadLine();
return;
}
control = false;
break;
case "M":
control = false;
metroid();
break;
case "A":
control = false;
Array();
break;
default: Console.WriteLine("No match");
break;
}
}
}
public class constructor
{
public string a = "This is a constructor!";
}
static public void metroid()
{
string b = "This is a method!";
Console.WriteLine(b);
}
static public void Array()
{
try
{
Console.WriteLine("This is a random array. Please enter the size.");
string sSize = Console.ReadLine();
int arraySize = Convert.ToInt32(sSize);
int[] size = new int[arraySize];
Random rd = new Random();
Console.WriteLine();
for (int i = 0; i < arraySize; i++)
{
size[i] = rd.Next(arraySize);
Console.WriteLine(size[i].ToString());
}
}
catch (System.FormatException)
{
Console.WriteLine("Not correct format, restarting array process.");
Array();
}
}
}
}
Here's what I came up with. You had too many ways of exiting your loop, so I removed all of the control = false lines except where the user typed "EXIT"
Also, in case "C" you return out of the method if they choose "Y", I changed that to continue so that the loop would continue.
Finally, I moved the 3 instruction statements into the loop, so when the user hit "Y" it would print those again.
static void Main(string[] args)
{
string _a = "";
constructor con = new constructor();
bool control = true;
while (control)
{
Console.WriteLine("Enter enter exit to end the program...");
Console.WriteLine("Enter C for constructor, M for method, A for an array...");
Console.WriteLine("Please reference source code to have full details and understanding...");
_a = Console.ReadLine();
switch (_a.ToUpper())
{
case "EXIT":
Console.WriteLine("Thank you for using AJ's program...");
control = false;
break;
case "C":
Console.WriteLine(con.a);
Console.WriteLine("Would you like to test another scenario?");
_a = Console.ReadLine(); //<==problem #1 you didnt set your var name
if (_a.ToUpper() == "Y")
{
continue; //<==problem #2 return exits the program, continue, just keeps going
}
control = false;
break;
case "M":
metroid();
break;
case "A":
Array();
break;
default:
Console.WriteLine("No match");
break;
}
}
}
I think you should considering goto in this case. Yes you need to put some extra effort, but it will help you overcoming the While loop.
A sample below:
switch (_a.ToUpper())
{
case "EXIT":
Console.WriteLine("Thank you for using AJ's program...");
control = false;
// execute goto when your all line executes successfully
goto case "New";
case "New":
// some logic
}
See working sample here Goto-Switch
string NewInput= Console.ReadLine();
if (NewInput.ToUpper() == "Y")
{
//print some thing with console.writeline
//if after this you want to restart the loop then instead of return use
continue;
}
Try putting the Console.Writeline inside the while loop like this:
static void Main(string[] args)
{
bool control = true;
while (control)
{
Console.WriteLine("Enter enter exit to end the program...");
Console.WriteLine("Enter C for constructor, M for method, A for an array...");
Console.WriteLine("Please reference source code to have full details and understanding...");
string _a = Console.ReadLine();
switch (_a.ToUpper())
{
case "EXIT":
Console.WriteLine("Thank you for using AJ's program...");
control = false;
break;
case "C":
Console.WriteLine("press c");
Console.WriteLine("Would you like to test another scenario?");
Console.ReadLine();
if (_a.ToUpper() == "Y")
{
Console.ReadLine();
return;
}
control = false;
break;
case "M":
control = false;
metroid();
break;
case "A":
control = false;
Array();
break;
default: Console.WriteLine("No match");
break;
}
}
}
Additional reading about switch here and here.
Just add comment for the result, thanks. Hope this helped!
may be you want to change
Console.ReadLine();
if (_a.ToUpper() == "Y")
{
Console.ReadLine();
return;
}
as
_a = Console.ReadLine();
if (_a.ToUpper() == "Y")
{
_a = Console.ReadLine();
continue;
}

C# integer validation

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
}

Console.ReadKey(); and Switch statement - using letters

I'm trying to make a program in C# that basically functions based on the key a user presses (ex. X = Quit, D = Disconnect, etc;) by using Console.ReadKey(); in c#
The problem I'm running into is how to use the ReadKey info in a Switch statement.. Can someone help please? The code is below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Switch_Test
{
class Program
{
static void Main()
{
Console.WriteLine("Welcome. Please enter your command: ");
string chinput;
int input;
bool activated = false;
input = Console.ReadKey();
chinput = Convert.ToChar(input);
switch (chinput)
{
case 'x':
{
Console.WriteLine("You pressed x...");
break;
}
case 'y':
{
Console.WriteLine("You pressed y..");
break;
}
case 'd':
{
if (activated != true)
{
Console.WriteLine("Please activate first!");
break;
}
else
{
Console.WriteLine("Active..");
break;
}
}
case 'a':
{
if (activated != true)
{
activated = true;
Console.WriteLine("Activating..");
break;
}
else
{
activated = false;
Console.WriteLine("Deactivating.");
break;
}
}
default:
Console.WriteLine("Unknown Command.");
break;
}
}
}
}
I know that's probably really wrong but I originally started with Console.ReadLine(); , the only difference is I want it to activate a function when you press a single key rather than having to hit enter or being able to type in different keys. Thanks in advance!
First of all, Convert.ToChar() doesn't work on ConsoleKeyInfo structure, so that's why you have problems, this conversion will throw an Exception.
You don't have to convert your key to character, instead, you can switch on .Key property, which is an enumerable that contains every key:
var input = Console.ReadKey();
switch (input.Key) //Switch on Key enum
{
case ConsoleKey.X:
break;
case ConsoleKey.Y:
break;
}
Edit:
You can also use input.KeyChar to get what you tried first - character, then you can switch on it if you want to, but it's harded to switch on different keys like arrows etc.
If you care if letter is capital/small, you can use .KeyChar or use .Key with .Modifiers to check if shift key was pressed when user typed the letter
You can simply take input as:
char input=Console.ReadKey().KeyChar;
using Console.ReadKey() returns a type of a struct ConsoleKeyInfo. so you need to recieve the return in a variable from this type.
Then switch on the Key enumrator, that has all characters.
ConsoleKeyInfo chinput = Console.ReadKey();
switch (chinput.Key)
{
case ConsoleKey.X:
{
Console.WriteLine("You pressed x...");
break;
}
case ConsoleKey.Y:
{
Console.WriteLine("You pressed y..");
break;
}
case ConsoleKey.D:
{
if (activated != true)
{
Console.WriteLine("Please activate first!");
break;
}
else
{
Console.WriteLine("Active..");
break;
}
}
case ConsoleKey.A:
{
if (activated != true)
{
activated = true;
Console.WriteLine("Activating..");
break;
}
else
{
activated = false;
Console.WriteLine("Deactivating.");
break;
}
}
default:
Console.WriteLine("Unknown Command.");
break;
}

Categories