I am writing a simple calculator where the user can perform operations and end the program by entering -1.
How can I modify how I take input from the user so that they can use the escape key instead of entering -1?
using System;
namespace A_4
{
class Calculator
{
public static void Main(string[] args)
{
Console.WriteLine("\tSimple Calculator");
while (true)
{
Console.WriteLine("********************************");
Console.Write("Enter First Number: ");
double operand1 = Convert.ToDouble(Console.ReadLine());
if (operand1 == -1)
{
break;
}
Console.Write("\nEnter Second Number: ");
double operand2 = Convert.ToDouble(Console.ReadLine());
if (operand2 == -1)
{
break;
}
Console.Write("\nEnter operator +, -, *, /): ");
// ... operate on the entered input
}
}
}
Since you want to get a specific key, you'll not be able to use Console.ReadLine, you have to read each character to be able to determine if ESC was pressed.
The best would be to create a helper method to get user input:
public static double GetUserInput()
{
string numbersEntered = "";
ConsoleKeyInfo lastKey;
// read keys until Enter is pressed
while ((lastKey = Console.ReadKey()).Key != ConsoleKey.Enter)
{
// if Escape is pressed, exit
if (lastKey.Key == ConsoleKey.Escape)
{
return -1;
}
// otherwise, add the key entered to the input
numbersEntered += lastKey.KeyChar.ToString();
}
// and convert the final number to double
return Convert.ToDouble(numbersEntered);
}
With that, you can just do double operand1 = GetUserInput(); and you know that if it's -1 (as an example), you have to exit.
Related
I am a beginner in C# programming and trying to code an app that reads the user input using a do-while loop, however, the loop doesn't continue executing when the user answers the question. I only want the loop to stops when enter is pressed
This is what I have done so far
Thanks in advance!
//call method to read a text, calculate and display the num of chars
private void ShowStringLength() {
ConsoleKeyInfo cki;
do
{
Console.WriteLine("Let me calculate the length of strings for you!");
Console.WriteLine("Give me text of any length, or press ENTER to exit!");
Console.Write("Enter a string : ");
String str = Console.ReadLine();
Console.WriteLine(str.ToUpper());
int len = str.Length;
Console.WriteLine("Numer of Chars is : " + len);
//Reads “Enter” from the keyboard to exit the app
cki = Console.ReadKey();
Console.Write("OK. You pressed Enter. See you agian!");
} while (cki.Key != ConsoleKey.Enter);
The cki = Console.ReadKey(); waits for any key input, not just enter. This makes the text "OK. You pressed Enter. See you agian!" show even if you actually pressed another key.
You could instead check the entered string, and exit the loop if it is empty. Example:
while (true)
{
Console.WriteLine("Let me calculate the length of strings for you!");
Console.WriteLine("Give me text of any length, or press ENTER to exit!");
Console.Write("Enter a string : ");
string str = Console.ReadLine();
// If the string is null, empty or only contains white spaces,
// break out of the loop.
if (string.IsNullOrWhiteSpace(str))
{
Console.Write("OK. You pressed Enter. See you agian!");
break;
}
Console.WriteLine(str.ToUpper());
Console.WriteLine("Numer of Chars is : " + str.Length);
};
I would try
if(Console.KeyAvailable)
{
cki = console.ReadKey();
...
}
You were close:
private void ShowStringLength()
{
ConsoleKeyInfo cki;
do
{
Console.WriteLine("Let me calculate the length of strings for you!");
Console.WriteLine("Give me text of any length, or press ENTER to exit!");
Console.Write("Enter a string : ");
String str = Console.ReadLine();
Console.WriteLine(str.ToUpper());
int len = str.Length;
Console.WriteLine("Numer of Chars is : " + len);
//Reads “Enter” from the keyboard to exit the app
cki = Console.ReadKey();
if (cki.Key == ConsoleKey.Enter)
{
Console.Write("OK. You pressed Enter. See you agian!");
}
else
{
Console.WriteLine(); //To start with a clean line
}
} while (cki.Key != ConsoleKey.Enter);
}
I wrote a code to made what you ant and i added a character ;in this sample space;
to determine that the string is finished. then calculated the length of string.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main()
{
Console.WriteLine("Press <Enter> to exit... ");
var outPutString = "";
var list = new List<int>();
while (true)
{
Console.WriteLine("Let me calculate the length of strings for you!");
Console.WriteLine("Give me text of any length, or press ENTER to exit!");
Console.Write("Enter a string End with space : ");
var readKey = Console.ReadKey().Key;
if (readKey == ConsoleKey.Enter)
{
Console.WriteLine(
$"Length of {outPutString} is : {(string.IsNullOrWhiteSpace(outPutString) ? 0 : outPutString.Length)}");
break;
}
while (readKey != ConsoleKey.Spacebar)
{
if (readKey == ConsoleKey.Enter)
{
Console.WriteLine(
$"Length of {outPutString} is : {(string.IsNullOrWhiteSpace(outPutString) ? 0 : outPutString.Length)}");
break;
}
var result = ((int) readKey);
list.Add(result);
outPutString = list.Aggregate(outPutString, (current, item) => current + (char) item);
list.Clear();
readKey = Console.ReadKey().Key;
}
Console.WriteLine(
$"Length of {outPutString} is : {(string.IsNullOrWhiteSpace(outPutString) ? 0 : outPutString.Length)}");
outPutString = "";
}
}
}
}
Hello i'm trying to create a calculator game but it loops only 2 times and (idk why)not til the user finds the result with input. And i'll later see how to make a random generator of numbers instead of writing them by myself in the code. Ty for helping.
Yassine
using System;
namespace G
{
class Program
{
static void Main(string[] args)
{
Calcul(2, 2);
}
static void Calcul(int nombre1, int nombre2)
{
int result = nombre1 + nombre2;
Console.WriteLine("Combien font " + nombre1 + " + " + nombre2);
int supposed = int.Parse(Console.ReadLine());
if(result != supposed)
{
Console.WriteLine("Try again!");
supposed = int.Parse(Console.ReadLine());
}
else
{
Console.Clear();
Console.WriteLine("Correct!");
}
}
}
}
You can change your if statement to a while loop whose condition is that the input does not match the result. We can also use int.TryParse with Console.ReadLine to handle cases where the user doesn't enter a valid number. This works by taking an out parameter that gets set to the parsed value if it's successful, and it returns a bool that indicates success. Perfect for a loop condition!
Then you can put the "success" message after the body of the while loop (because the only way to exit the loop is to get the correct answer). It would look something like:
static void Calcul(int nombre1, int nombre2)
{
int result = nombre1 + nombre2;
int input;
Console.Write($"Combien font {nombre1} + {nombre2} = ");
while (!int.TryParse(Console.ReadLine(), out input) || input != result)
{
Console.WriteLine("Incorrect, please try again.");
Console.Write($"Combien font {nombre1} + {nombre2} = ");
}
Console.WriteLine("Correct! Press any key to exit.");
Console.ReadKey();
}
I´m having problems with getting my code to work while using TryParse to catch if the user where to input a string instead of a int. If I use it as it looks now I only get the base value of 0 if something other than an int is input. I want it to show an error message to the user.
Have tried messing around with a number of different ways of using TryParse but none of them has really been helpfull.
static void Main(string[] args)
{
Random r = new Random();
int speltal = r.Next(1,21);
bool play = false;
int myNum;
while (!play)
{
Console.Write("\n\tGuess a number between 1 and 20: ");
Int32.TryParse(Console.ReadLine(), out myNum);
if (myNum < guessNum)
{
Console.WriteLine("\tThe number you have guessed is to low");
Console.ReadLine();
}
if (myNum > guessNum)
{
Console.WriteLine("\tThe number you have guessed is to high");
Console.ReadLine();
}
if (myNum == guessNum)
{
Console.WriteLine("\tCongratulations you guessed the right number!");
Console.ReadLine();
}
I want it show an error message to the user if they put in anything other than a int. It also have to include TryParse according to my teatcher
You're not capturing the bool output of TryParse so you have no idea if a non-numeric value was entered. Try something like this:
bool isValid;
do
{
Console.Write("\n\tGuess a number between 1 and 20: ");
isValid = Int32.TryParse(Console.ReadLine(), out myNum);
if(!isValid)
{
Console.WriteLine("\n\tInvalid input detected. Please try again.");
}
} while(!isValid)
The TryParse method can only put integers in the passed variable (as it is of type int), so if the value passed to it can't be parsed into an integer, the default value of int (0) will be assigned to the variable.
The way TryParse tell you if it successfully parsed the number or not, is by returning a boolean indicator.
You can try this:
while (true)
{
bool valid = int.TryParse(Console.ReadLine(), out myNum);
if(valid)
break;
Console.WriteLine("Input invalid. Please try again");
}
TryParse returns a Boolean which indicates if the input string was successfully parsed or not. Both of the answers above are correct on how to handle a invalid input but, here is a cleaner version which will also uphold the rule, between 1 and 20:
while (true)
{
Console.Write("\n\tGuess a number between 1 and 20: ");
//Checks to see if the input was successfully parsed to a integer also, performs a Trim on the input as to remove any accidental white spaces that a user might have typed in, e.g. "1000 "
if (int.TryParse(Console.ReadLine().Trim(), out myNum))
{
//Checks to see if the parsed number is in the specified range
if ((myNum > 0) && (myNum < 21))
{
break;
}
Console.WriteLine("\tThe input number was out of the specified range.");
}
else
{
Console.WriteLine("\tFailed to parse the input text.");
}
//Optional, makes the thread sleep so the user has the time to read the error message.
Thread.Sleep(1500);
//Optional, clears the console as to not create duplicates of the error message and the value of Console.Write
Console.Clear();
}
// Continue here, if (myNum < guessNum) . . .
You should use the bool returned by TryParse. Something that looks like this:
Updated answer:
static void Main(string[] args)
{
Random random = new Random();
int guessNum = random.Next(1, 21);
while(true)
{
Console.WriteLine("Guess the number between 1 and 21.");
if (Int32.TryParse(Console.ReadLine(), out int input))
{
if (input == guessNum)
{
Console.WriteLine($"You guessed it right. The number is {input}");
if(ShouldContinue())
{
guessNum = random.Next();
continue;
}
else
{
break;
}
}
if (input < guessNum)
Console.WriteLine("The number you guessed is smaller.");
else
Console.WriteLine("The number you guessed is bigger");
}
else
{
Console.WriteLine("Please enter a number between 1 and 21 as your guess");
}
}
}
static bool ShouldContinue()
{
while (true)
{
Console.WriteLine($"Do you want to continue playing? (y/n)");
string continueInput = Console.ReadLine().Trim().ToLower();
if (continueInput == "y")
return true;
else if (continueInput == "n")
return false;
else
Console.WriteLine("Invalid input!. Please choose 'y' or 'n'.");
}
}
Old answer:
while (true)
{
if (Int32.TryParse(inputInt, out int myNum))
{
// your logic goes here, too low/high or correct answer.
}
}
I am trying to create the menu for a mastermind game which can be ran in a command prompt using C#. The issue I am running into is capturing the users input for the menu. If they enter a 2 then it should display that they entered the number two and if not then it would say they have not displayed the number two.
The issue I am having is that it wont turn the users input into a working integer and will either come up saying that it can't explicitly convert from System.ConsoleKeyInfo to int or string to int.
using System;
namespace MasterMind
{
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(" MasterMind's Main Menu");
Console.WriteLine(" 1: Play");
Console.WriteLine(" 2: Help");
Console.WriteLine(" 0: Exit");
int userinput = Console.ReadKey();
if (Nuserinput == 2);
{
Console.WriteLine("This is a number 2");
}
else
{
Console.WriteLine("This is not a number 2");
}
}
}
}
Console.ReadKey() returns a ConsoleKeyInfo object, which is not an int object. You can get a char from that, for example:
var key = Console.ReadKey();
var keyChar = key.KeyChar;
If you expect that char value to represent an integer, you can convert it to one:
int keyInt = (int)Char.GetNumericValue(keyChar);
Aside from other error checking you might want to put in place in case the user doesn't enter a valid integer, this would at least get your the integer value you're looking for.
Console.ReadKey() returns a ConsoleKeyInfo, so you'll need to do something like this:
ConsoleKeyInfo data = Console.ReadKey();
int num;
if (int.TryParse(data.KeyChar.ToString(), out num) && num == 2)
{
Console.WriteLine("This is a number 2");
}else{
Console.WriteLine("This is not a number 2");
}
Change your
int userinput = Console.ReadKey();
if (Nuserinput == 2)
To:
string userInput = Console.ReadKey().KeyChar.ToString();
if(input == "2")
Or covert the string to an int as shown in other answers. But for this, a string works fine.
I'm making a program that has little programs inside of it, and I've come to a dilemma. On my first mini-program which rearranges digits to find the greatest possible number from those digits, it asks if the user wants to quit. If they respond "Yes" then the function returns 0 which is evaluated in the main(string[] args) method. My problem is that whenever the user says "No", the mini-program still doesn't continue. Here's my source:
namespace ACSL_Competition
{
class Program
{
static int DigitRearranger()
{
string[] mainString = {};
Console.WriteLine("---------Welcome to the Digit Re-arranger!---------");
Console.WriteLine("I take a positive number up to 10000, and find the highest number that can be made out of its digits.");
Console.WriteLine("Instructions: Enter a number up to 10000, and see the results!");
drLabel:
Console.Write("Your Number: ");
string input = Console.ReadLine();
int inputNumber = 0;
try { inputNumber = int.Parse(input); }
catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); goto drLabel; }
/*Placeholder code for the moment*/Console.WriteLine(inputNumber.ToString());
evaluate:
Console.Write("Do you want to exit? Yes/No: ");
if (Console.ReadLine().Equals("Yes"))
return 1;
else if (Console.ReadLine().Equals("No"))
{
goto drLabel;
}
else
{
return 1;
}
}
static void Main(string[] args)
{
Console.WriteLine("Welcome to the ACSL Competition Program. Choose a program to begin:");
Console.Write("\n\t");
Console.WriteLine("1\tDigit Re-arranger");
label:
Console.Write("\nProgram: ");
string input = Console.ReadLine();
int number = 0;
try { number = int.Parse(input); }
catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); goto label; }
if (number == 1)
{
Console.WriteLine("\n");
if (DigitRearranger() == 1)
{
goto label;
}
else if (DigitRearranger() != 1)
{
DigitRearranger();
}
}
else if (!number.Equals(1))
{
Console.WriteLine("Not a valid program.");
goto label;
}
//----------------
Console.ReadLine();
}
}
}
The underlying problem is that you're calling readline twice. The first time it gets the entered value, i.e. Yes, the second time you call it there is no data to read so it returns "". If you need to reuse the same input store it in a variable, i.e.
string inputVal = Console.ReadLine();
I hate goto statements, maybe you could restructure your code in to a while loop, something like:
bool exit = false;
while(!exit)
{
Console.Write("Your Number: ");
//Your main code
Console.Write("Do you want to exit? Yes/No: ");
if(Console.ReadLine() != "No")
exit = true;
}
In fact, you could get rid of the exit variable, just do while(true) and return if the user enters anything other than no.
I have a few suggestions:
Write your code to be more modular to improve readability. The Main() method should only drive the outer UI loop, each module provides its own UI.
Never use goto statements.
Don't use Console.Readline() inside an if condition (when not "Yes", it was called twice).
Here is my refactored version of your code:
class Program {
static void DigitRearranger()
{
string response = "";
int num;
do
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("---------Welcome to the Digit Re-arranger!---------");
Console.WriteLine("I take a positive number up to 10000, and find the highest number that can be made out of its digits.");
Console.WriteLine("Instructions: Enter a number up to 10000, and see the results!");
Console.ResetColor();
Console.Write("Your Number: ");
if (!int.TryParse(Console.ReadLine(), out num))
{
Console.WriteLine("Not a number. Press any key to continue");
Console.ReadKey();
continue;
}
//todo: reaarrange the number & print results
/*Placeholder code for the moment*/
Console.WriteLine(num);
Console.Write("Do you want to exit? Yes/No: ");
response = Console.ReadLine();
} while (response.ToLower() != "yes");
}
//UI driver only in Main method:
static void Main(){
string response = "";
do
{
Console.Clear();
Console.WriteLine("Welcome to the ACSL Competition Program. Choose a program to begin:");
Console.WriteLine("\n\t1\tDigit Re-arranger");
Console.WriteLine("\tq\tQuit");
Console.Write("\nProgram: ");
response = Console.ReadLine();
switch(response)
{
case "1":
DigitRearranger();
break;
case "q":
break;
default:
Console.WriteLine("Not a valid program. Press any key to continue");
Console.ReadKey();
break;
}
} while (response.ToLower() != "q");
Console.ReadLine();
}}