I want to make a calculator that asks what you want to do, e.g. add, subtract, etc. It should then use if-statements to perform the different kinds of calculations.
But now when I have gotten to division, I'm wondering how to handle division by 0. I want the program to warn the user when he/she enters a 0, saying something like "sorry you can't divide by 0".
I still want it to calculate the result if the denominator isn't 0.
The error i get is that i can't write:
if (Num02 == "0") because I can't use ints or doubles etc.
How do I fix this in a nice way to show my class/teacher next week?
Here's my code:
using System;
namespace Calculator
{
class MainClass
{
static void Main(string[] args)
{
Start:
int Num01;
int Num02;
string Answer;
Console.WriteLine("What do you want to do?");
Answer = Console.ReadLine();
if (Answer == "Division")
{
Console.WriteLine("Write number");
Num01 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Divided by?");
Num02 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(Num01 + "/" + Num02 + "=" +
(Num01 / Num02));
}
}
}
}
the error i seem to get is that i cant write:
"if (num02 == "0")" because i cant use ints or doubles etc.
You were most certainly on the right track. By adding quotes around the "0", you were comparing a variable of type int (Num02) with a string. Instead, use a literal 0 (without quotes):
if (Num02 == 0)
{
// print warning here
}
else
{
// do division and print result
}
I suggest extracting method for the user input (where we can check syntax - what if user put bla-bla-bla instead of number, extra condition(s) - we don't accept 0 as a second number etc.):
private static int ReadValue(string title,
Func<int, bool> extraCondition = null,
string extraConditionText = null) {
int result;
while (true) { // keep on asking until correct input provided
Console.WriteLine(title);
if (!int.TryParse(Console.ReadLine(), out result)) // syntax check
Console.WriteLine("Syntax error, please, input integer value");
else if (extraCondition != null && !extraCondition(result)) // extra check if any
Console.WriteLine(string.IsNullOrEmpty(extraConditionText)
? "Incorrect value"
: extraConditionText);
else
return result;
}
}
Then you can put
static void Main(string[] args) {
while (true) {
int Num01;
int Num02;
Console.WriteLine("What do you want to do?");
string Answer = Console.ReadLine().Trim();
if (string.Equals(Answer, "Quit", StringComparison.OrdinalIgnoreCase)) {
break;
}
else if (string.Equals(Answer, "Division", StringComparison.OrdinalIgnoreCase)) {
Num1 = ReadValue("Write number");
Num2 = ReadValue("Divided by?", x => x != 0, "Sorry you can't divide by 0");
Console.WriteLine($"{Num1} / {Num2} = {Num1 / Num2}");
}
else {
Console.WriteLine("Sorry, it's an incorrect option");
}
}
}
Related
I'm new to coding and trying my best but I got stuck. Again.
So. I need to calculate the product of some random numbers using do while.
You type the numbers and when you type x, the loop needs to close showing the result. If you ONLY type x, it needs to show "1".
I can't manage to only show "1" when you type "x".
I have this:
int product = 1;
Console.WriteLine();
String input = Console.ReadLine();
do
{
int n = Convert.ToInt32(input);
product = product * n;
input = Console.ReadLine();
} while (!input.ToLower().Equals("x"));
Console.WriteLine(product);
Console.ReadLine();
for and while breaks in the start of the loops and do while break at the end, sometimes you have to break it the middle (here after the input was entered, if it's x) and before the accumulation.
The best way to manage this is an infinite loop for(;;) or while(true) and uses of break:
var product = 1;
for(;;)
{
var input = Console.ReadLine();
if (input is null || input.Equals("x", StringComparison.OrdinalIgnoreCase))
break;
product *= Convert.ToInt32(input);
}
Console.WriteLine(product);
Console.ReadLine();
Or you can try to make it fit (mostly double calls to ReadLine).
A for version that looks ugly:
var product = 1;
for (var input = Console.ReadLine(); input != "x"; input = Console.ReadLine())
{
product *= int.Parse(input);
}
Console.WriteLine(product);
Console.ReadLine();
A while version:
var product = 1;
var input = Console.ReadLine();
while (!input.ToLower().Equals("x"))
{
product *= Convert.ToInt32(input);
input = Console.ReadLine();
}
Console.WriteLine(product);
Console.ReadLine();
Another while version that avoid ReadLine at multiple places:
var product = 1;
string input;
// an affectation actually evaluate to the value affected
// avoid this since it's not easily readable (= and == mismatch)
while ((input = Console.ReadLine()) != "x")
{
product *= Convert.ToInt32(input);
}
Console.WriteLine(product);
Console.ReadLine();
A do while version:
I add it because it's in the question title, otherwise I didn't consider it a good solution.
Based on yassinMi answer.
var product = 1;
var input = "1";
do
{
product *= int.Parse(input);
input = Console.ReadLine();
} while (input != "x");
Console.WriteLine(product);
Console.ReadLine();
A Linq version:
var product = Enumerable.Range(0, int.MaxValue) // many elements
.Select(_ => Console.ReadLine()) // discard them and take the console input
.TakeWhile(s => s != "x") // stop on 'x'
.Select(int.Parse) // parse to int
.Aggregate(1, (a, b) => a * b); // accumulate from 1 and by making the product
Console.WriteLine(product);
Console.ReadLine();
a simple fix: change the line
String input = Console.ReadLine();
to
String input = "1";
otherwise you would use the while loop, or add extra if statement..
Welcome to C#!
Your issue is most likely due to an error while converting a value. You are trying to convert "x" to int, but "x" is a letter, which cannot be converted to a number.
Cause of the issue
The problem of this program is that you are trying to convert a letter to a number. This is not possible in real life, and less possible in programming! A computer is not able to convert a number to a letter, unless you are explaining to it how, or if your handle the error properly.
The following line:
int n = Convert.ToInt32(input);
...Does not check for what has been entered. Convert.ToInt32() will throw an exception if the string? (From Console.ReadLine()) could not be converted.
The fix
To fix this issue, you need to handle the input of the user. Literally anything is accepted by Console.ReadLine() but you want a value that can be converted to a int.
The int type has a built-in function to convert a value without throwing an exception if it couldn't be converted, instead, it returns a bool (Either true or false).
So the following changes need to be brought to your program:
int product = 1;
string ? input;
do {
input = Console.ReadLine();
// Try to parse to integer, if it couldn't be parsed to integer, continue.
if (!int.TryParse(input, out int n)) {
continue;
}
product = product * n;
} while (!input.Equals("x", StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine(product);
// End of the program
Console.WriteLine("Press any key to quit the program.");
Console.ReadKey();
Trying to parse a string to an integer
The method int.TryParse(string? input, out int output); allows you to try to convert a string to a int.
If the method fails, instead of throwing an Exception, it will returns false.
Getting the output value
The output value can be obtained from out int output, out allows you to output a value from a function.
The logic would be that if int.TryParse(...) returns true, the value can be used, otherwise you can continue.
The continue statement tells your loop that the current loop should be skipped and goes to the next one (= At the beginning of your loop).
Other changes
I've brought to your program some changes to make it more readable and easier to edit.
Firstly, you'd want to use Equals(input, StringComparison.InvariantCultureIgnoreCase) instead of ToLowerCase(), the result is the same and it is cleaner! ๐
Also, you can directly ask the input within your while loop since this will be repeated each time, you just need to position it correctly so the value can be verified.
Final program
ConsoleKeyInfo continueProgram = new ConsoleKeyInfo();
ConsoleKeyInfo continueInput = new ConsoleKeyInfo();
List<int> products = new List<int>();
do
{
Console.Clear();
do
{
Console.Write("\nPlease enter new number . . . ");
if (int.TryParse(Console.ReadLine(), out int result))
{
products.Add(result);
Console.WriteLine("\nNew Product Added!");
}
else
{
Console.WriteLine("\nYou have entered a value that is not an integer!\n");
}
Console.Write("\nDo you want to enter an other value (press Y) or any key to exit . . . ");
continueInput = Console.ReadKey();
Console.WriteLine();
}
while (continueInput.Key == ConsoleKey.Y);
Console.WriteLine();
foreach (var item in products)
{
Console.WriteLine(item.ToString());
}
Console.ReadLine();
Console.Write("\n\nPress 'Y' to continue or any other key to exit! . . . ");
continueProgram = Console.ReadKey();
} while (continueProgram.Key == ConsoleKey.Y);
The problem is that Console.ReadLine() gets called twice before checking for x. The first input gets eaten up.
What you need to do is inside the loop ask and process the input, and exit the loop when the condition is met.
One way of doing this is by keeping a boolean value called done indicating when to exit the loop'
static void Main(string[] args)
{
int product = 1;
bool done = false;
do
{
Console.WriteLine("Enter number or 'x' to calculate result.");
string input = Console.ReadLine();
done = input.ToLower() == "x";
if (int.TryParse(input, out int value))
{
product *= value;
}
else
{
Console.WriteLine("Input ignored.");
}
} while (!done);
Console.WriteLine($"The product is {product}");
}
Another more succinct way is to use the break; statement
static void Main(string[] args)
{
int product = 1;
do
{
Console.WriteLine("Enter number or 'x' to calculate result.");
string input = Console.ReadLine();
if (input.ToLower() == "x")
{
// this exits the loop
break;
}
if (int.TryParse(input, out int value))
{
product *= value;
}
else
{
Console.WriteLine("Input ignored.");
}
} while (true);
Console.WriteLine($"The product is {product}");
}
Also, it is recommended to use int.TryParse(string, out integer) for better handling weird user inputs instead of Convert.ToInt32(). See the pattern above on how it is used.
Can someone help me modify my work? Help me add:
An error message when the user tries to enter decimal values.
A third operand for the calculator.
An error message when the user tries to enter any string value other than โexitโ.
Here's my code:
class Program
{
static void Main(string[] args)
{
do
{
Console.Write("x = ");
string str = Console.ReadLine();
if (str == "exit")
{
Console.WriteLine("The Programme has stopped");
continue;
}
else
{
int x = Convert.ToInt32(str);
Console.Write("y = ");
int y = Convert.ToInt32(Console.ReadLine());
int sum = x / y;
Console.WriteLine("Result: {0}", sum);
}
}
while (true);
}
}
I'd be very grateful.
Here is a function you can use:
public static bool HasDecimals(decimal x) {
return Decimal.Round(x, 0) != x;
}
If I were going to do this, I'd create a function that I can use to handle most of the user interaction (emitting the prompt, parsing the input string, deciding if "Exit" was entered). In the code below, I kinda-sorta use the standard TryGetXxx pattern.
In this code below, if the TryGetDecimalValueWithPrompt returns true, then a properly parsed number is returned in the output. If it returns false, then the user has chosen to quit.
So, I start with that function:
public static bool TryGetDecimalValueWithPrompt(string prompt, out decimal outputValue)
{
while (true)
{
Console.Write(prompt + " > ");
var response = Console.ReadLine();
if (response.Equals("exit", StringComparison.OrdinalIgnoreCase) || response.Equals("quit", StringComparison.OrdinalIgnoreCase))
{
outputValue = 0.0m;
return false;
}
if (decimal.TryParse(response, out outputValue))
{
return true;
}
//otherwise, failure, so try again
Console.WriteLine("Sorry, incorrect format, try entering a correctly formatted decimal again");
}
}
The while(true) statement says Loop Forever. In this case, Forever lasts until the user has entered a properly formatted number or one of the "exit" keywords.
Then I construct my program around it:
if (!TryGetDecimalValueWithPrompt("Enter the first operand", out var operand1))
{
return;
}
if (!TryGetDecimalValueWithPrompt("Enter the second operand", out var operand2))
{
return;
}
if (operand2 == 0.0m)
{
Console.WriteLine("Sorry, you can't divide by zero");
return;
}
Console.WriteLine($"The result of op1/op2 is {operand1 / operand2}");
If you don't want to allow decimals being entered, change the TryGetDecimalValueWithPrompt function to work with integers instead:
public static bool TryGetIntValueWithPrompt(string prompt, out int outputValue)
{
while (true)
{
Console.Write(prompt + " > ");
var response = Console.ReadLine();
if (response.Equals("exit", StringComparison.OrdinalIgnoreCase) || response.Equals("quit", StringComparison.OrdinalIgnoreCase))
{
outputValue = 0;
return false;
}
if (int.TryParse(response, out outputValue))
{
return true;
}
//otherwise, failure, so try again
Console.WriteLine("Sorry, incorrect format, try entering a correctly formatted integer again");
}
}
If you work with integers, remember that integer division always yields an integer. For example, if you use integers in 7 / 2, the result will be 3, not 3.5. If you want 3.5, do something like 7 / (decimal) 2 (at that point, you are dividing an integer by a decimal and you'll get a decimal).
By the way, if you wanted to prompt for the operator (+, -, *, or /), you could create a TryGetOperator function in the same pattern and just check whatever you get from the user with something like:
var operators = new[] { "+", "-", "*", "/" };
bool goodOperator = operators.Contains(inputFromUser);
Is there a way to ignore a line/block of code if the condition is met?
I'm doing a C# .NET tutorial, and the application is a number guessing game.
I added a hint option if the user enters a wrong number (else if part):
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
AskForAHint(correctNumber);
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
Basically I am asking a user if he wants a hint, and if he writes Y, the hint will be displayed. However, is there an option to display this question only once since this if statement is included in a while loop?
It would be annoying if "Do you want a hint?" question keeps displaying even if the user says Y.
My AskForAHint function:
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Thanks
Another way to do it would be to make the number of hints configurable (allowing the caller to specify how many hints they want to let the user ask for), and then keep track of the number of hints given in the method itself.
This would require a slight change to the AskForAHint method, however, since we don't know if the user answered "Y" or "N" to the hint question. Since AskForHint has no return value, we could have it return a bool that indicates how the user responded to the question:
static bool AskForAHint(int num)
{
var answer = GetUserInput("Do you want a hint? [Y/N]: ", ConsoleColor.Yellow);
if (!answer.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
{
return false;
}
var beginning = num - num % 10;
var finish = beginning + 10;
Console.WriteLine($"The correct number is somewhere between {beginning} and {finish}");
return true;
}
Now we can keep track of how many hints the user has received by incrementing a counter in our "Game" method:
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
To test out the sample code above, I used this method below, which also allows us to configure how many total guesses the user has, what the min and max values of the range should be, and if they should be given a "directional hint", like "too high!" or "too low!":
private static readonly Random Random = new Random();
private static void PlayGuessingGame(int maxHints = 1, int maxGuesses = 10,
int rangeMin = 1, int rangeMax = 100, bool giveDirectionalHint = true)
{
if (rangeMax < rangeMin) rangeMax = rangeMin;
var correctNumber = Random.Next(rangeMin, rangeMax + 1);
var guessCount = 0;
var hintCount = 0;
WriteMessage("Welcome to the guessing game!", ConsoleColor.White);
WriteMessage("-----------------------------\n", ConsoleColor.White);
WriteMessage($"I'm thinking of a number from {rangeMin} to {rangeMax}. ", ConsoleColor.Green);
WriteMessage("Let's see how many guesses it takes you to guess it!\n", ConsoleColor.Green);
do
{
WriteMessage($"(You have {maxGuesses - guessCount} guesses left)");
var input = GetUserInput("Enter the number I'm thinking of: ", ConsoleColor.White);
int guess;
if (!int.TryParse(input, out guess))
{
WriteMessage("Please enter a whole number", ConsoleColor.Red);
continue;
}
// Only increment guesses if they entered an actual number
guessCount++;
if (guess == correctNumber) break;
if (Math.Abs(guess - correctNumber) == 2)
{
WriteMessage("You are close!!", ConsoleColor.DarkCyan);
}
if (giveDirectionalHint)
{
WriteMessage("Wrong number - too " + (guess < correctNumber ? "low!" : "high!"),
ConsoleColor.Red);
}
else
{
WriteMessage("Wrong number, please try again", ConsoleColor.Red);
}
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
} while (guessCount < maxGuesses);
WriteMessage("You are CORRECT!", ConsoleColor.Yellow);
GetKeyFromUser("\nDone! Press any key to exit...");
}
This uses the helper functions:
public static void WriteMessage(string message, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
private static string GetUserInput(string prompt, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.Write(prompt);
Console.ResetColor();
return Console.ReadLine();
}
Output
You can see in the output below, I was only given a single hint. However that, combined with the directional hints, made the game easy to win:
I think you can do an "if" with a counter.
Try It
Int cont = 0; //global
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
if(cont == 0){
AskForAHint(correctNumber);
}
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
And in the function add
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
cont = 1;
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Use a Member Variable Boolean, its similar to how you can avoid recursive calls.
private bool alreadyHinted = false;
static void AskForAHint(int num)
{
if (alreadyHinted) return;
alreadyHinted = true;
At some point you will need to set alreadyHinted back to false;
class Program
{
static void Main(string[] args)
{
string choice = string.Empty;
do
{
start:
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (number < 1000)
{
switch (conversion)
{
case true:
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
break;
case false:
Console.WriteLine("ERROR: INVALID INPUT!");
goto start;
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
return;
}
do // Here is the beginning of the do code
{
Console.WriteLine("\n Do you want to continue - Yes or No");
choice = Console.ReadLine();
if (choice.ToUpper() != "YES" && choice.ToUpper() != "NO")
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
} while (choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
} while (choice.ToUpper() == "YES");
}
}
I'm using several do while loops in this statement however I'm trumped on how I would put in a loop "ERROR INVALID INPUT:" result when a user puts in anything other than the limits of the assigned integers (i.e. putting decimals or fractions) or if they put a string. I simply used goto because I'm having trouble finding out where to put the do while loop statement. If someone could simply show me how I might replace that one goto with a do while loop then I would be very greatful. (Note if you show me ways I could optimize my code better since I'm still new I probably won't understand it but your welcome to give it your best shot!)
Short answer:
The keyword continue means to go back to the beginning of the loop. Note that this will recheck the loop condition and break if it is false. Also, most people find do-while loops less readable (and they are really rarely necessary), so try using while loops instead.
There is also the keyword break which will simply exit the loop. (not just for switch-case!)
A more readable version would look something like this:
string userAnswer = "yes";
// while is usually more readable than do-while
while (userAnswer == "yes")
{
Console.WriteLine("Please input a number for it to be counted!");
int number;
// Ask for new input until the user inputs a valid number
while (!int.TryParse(Console.ReadLine(), out number))
{
Console.WriteLine("Invalid number, try again");
}
if (number < 1000)
{
// Print from 0 to number, jumping in 2's
for (int i = 0; i <= number; i += 2)
Console.WriteLine(i + " ");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
continue; // Jump back to the start of this loop
}
Console.WriteLine("Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
// Ask for new input until the user inputs "Yes" or "No"
while (userAnswer != "yes" && userAnswer != "no")
{
Console.WriteLine("Invalid input. Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
}
}
Hey I'll post some code that may help and offer some advice. Basically declare a bool named 'loopCompleted' which will continue the do while loop until you set it to true. The downside is that it will not instantly exit the loop like return/goto/etc but this is not a problem in most cases.
You may want to use if/else instead of switch(conversion), its sort of interesting to see it done that way but its a bit over the top :)
If Int.TryParse() doesnt already return false for fractional values (e.g. [15.08] returns [true] with [15] ). Then you can store Console.ReadLine() before using TryParse, then use stringName.Contains() to check for the '.' Basically, if the conversion succeeds you also check if it contained the decimal point.
Another way to check is to do float.TryParse() then check if it is a fractional value.
bool fraction = false;
if( number % 1.0f > 0)
fraction == true;
% is called modulus, it returns the remainder of A / B
If a number has a remainder when divided by 1 it must be a fractional value.
//start:
bool loopCompleted = false;
do
{
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (conversion && number < 1000)
{
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
loopCompleted = true;
}
else
{
if(conversion == false)
{
Console.WriteLine("ERROR: INVALID INPUT!");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
}
}
} while(!loopCompleted)
Console.WriteLine("Enter the cost of the item");
string input = Console.ReadLine();
double price = Convert.ToDouble(input);
Hello, I want the keyboard buttons, A-Z, brackets, question mark, etc to be disabled. I want it so if you type it in, it will not show up in the Console. I only want the numbers 1-9 to show up. This is in C# Console application. Thanks for the help!
try this code snippet
string _val = "";
Console.Write("Enter your value: ");
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace)
{
double val = 0;
bool _x = double.TryParse(key.KeyChar.ToString(), out val);
if (_x)
{
_val += key.KeyChar;
Console.Write(key.KeyChar);
}
}
else
{
if (key.Key == ConsoleKey.Backspace && _val.Length > 0)
{
_val = _val.Substring(0, (_val.Length - 1));
Console.Write("\b \b");
}
}
}
// Stops Receving Keys Once Enter is Pressed
while (key.Key != ConsoleKey.Enter);
Console.WriteLine();
Console.WriteLine("The Value You entered is : " + _val);
Console.ReadKey();
This MSDN article explains how to read characters one at a time in a console window. Test each character as it is input with the Char.IsNumber() method, and reject those characters that fail the test.
In a while, I got a solution really short:
double number;
Console.Write("Enter the cost of the item: ");
while (!double.TryParse(Console.ReadLine(), out number))
{
Console.Write("This is not valid input. Please enter an integer value: ");
}
Console.Write("The item cost is: {0}", number);
See you!
Here is one approach. It's probably overkill if you're just starting out in C#, since it uses some more advanced aspects of the language. In any case, I hope you find it interesting.
It has some nice features:
The ReadKeys method takes an arbitrary function for testing whether the string so far is valid. This makes it easy to reuse whenever you want filtered input from the keyboard (e.g. letters or numbers but no punctuation).
It should handle anything you throw at it that can be interpreted as a double, e.g. "-123.4E77".
However, unlike John Woo's answer it doesn't handle backspaces.
Here is the code:
using System;
public static class ConsoleExtensions
{
public static void Main()
{
string entry = ConsoleExtensions.ReadKeys(
s => { StringToDouble(s) /* might throw */; return true; });
double result = StringToDouble(entry);
Console.WriteLine();
Console.WriteLine("Result was {0}", result);
}
public static double StringToDouble(string s)
{
try
{
return double.Parse(s);
}
catch (FormatException)
{
// handle trailing E and +/- signs
return double.Parse(s + '0');
}
// anything else will be thrown as an exception
}
public static string ReadKeys(Predicate<string> check)
{
string valid = string.Empty;
while (true)
{
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
{
return valid;
}
bool isValid = false;
char keyChar = key.KeyChar;
string candidate = valid + keyChar;
try
{
isValid = check(candidate);
}
catch (Exception)
{
// if this raises any sort of exception then the key wasn't valid
// one of the rare cases when catching Exception is reasonable
// (since we really don't care what type it was)
}
if (isValid)
{
Console.Write(keyChar);
valid = candidate;
}
}
}
}
You also could implement an IsStringOrDouble function that returns false instead of throwing an exception, but I leave that as an exercise.
Another way this could be extended would be for ReadKeys to take two Predicate<string> parameters: one to determine whether the substring represented the start of a valid entry and one the second to say whether it was complete. In that way we could allow keypresses to contribute, but disallow the Enter key until entry was complete. This would be useful for things like password entry where you want to ensure a certain strength, or for "yes"/"no" entry.
This code will allow you to:
Write only one dot (because numbers can have only one decimal separator);
One minus at the begining;
One zero at the begining.
It means that you not be able to write something like: "00000.5" or "0000...-5".
class Program
{
static string backValue = "";
static double value;
static ConsoleKeyInfo inputKey;
static void Main(string[] args)
{
Console.Title = "";
Console.Write("Enter your value: ");
do
{
inputKey = Console.ReadKey(true);
if (char.IsDigit(inputKey.KeyChar))
{
if (inputKey.KeyChar == '0')
{
if (!backValue.StartsWith("0") || backValue.Contains('.'))
Write();
}
else
Write();
}
if (inputKey.KeyChar == '-' && backValue.Length == 0 ||
inputKey.KeyChar == '.' && !backValue.Contains(inputKey.KeyChar) &&
backValue.Length > 0)
Write();
if (inputKey.Key == ConsoleKey.Backspace && backValue.Length > 0)
{
backValue = backValue.Substring(0, backValue.Length - 1);
Console.Write("\b \b");
}
} while (inputKey.Key != ConsoleKey.Enter); //Loop until Enter key not pressed
if (double.TryParse(backValue, out value))
Console.Write("\n{0}^2 = {1}", value, Math.Pow(value, 2));
Console.ReadKey();
}
static void Write()
{
backValue += inputKey.KeyChar;
Console.Write(inputKey.KeyChar);
}
}
You can do it with a single line code as follows:
int n;
Console.WriteLine("Enter a number: ");
while (!int.TryParse(Console.ReadLine(), out n)) Console.WriteLine("Integers only allowed."); // This line will do the trick
Console.WriteLine($"The number is {n}");
You can change int into double in case you wanted to allow double instead of integers and so on.
string input;
double price;
bool result = false;
while ( result == false )
{
Console.Write ("\n Enter the cost of the item : ");
input = Console.ReadLine ();
result = double.TryParse (input, out price);
if ( result == false )
{
Console.Write ("\n Please Enter Numbers Only.");
}
else
{
Console.Write ("\n cost of the item : {0} \n ", price);
break;
}
}