c# try and catch/ error handling - c#

I am currently working on a program and I am finalising it by going over with error handling. I have several cases which look like:
int stockbankInput = Convert.ToInt32(Console.ReadLine());
Here, the user must enter either 1, 2, 3. I have tried to use an if statement to catch the error if anybody inputs a blankspace/string/character or a number that is not 1,2 or 3 but it doesn't work in the same sense as a string input. Below is what I have tried:
if(stockbankInput == null)
{
Console.WriteLine("Error: Please enter either 1, 2 or 3");
stockbankInput = 0;
goto menuRestartLine;
}
However, you cannot link 'null' with an integer input, only a string. Can anybody help with this please?

Use the Int32 TryParse method:
int input;
var successful = Int32.TryParse(Console.ReadLine(), out input);
if (!successful)
// do something else
else
return input;

You're checking if an int is null, which will always return false because an int cannot be null.
You can use 'int?' (Nullable int) but Convert.ToInt32 will not return null. If the value of the int cannot be resolved it will resolve to the default value of zero. You can either check if the returned int is zero or do some further checking of the returned string:
int input = 0;
string errorMessage = "Error: Please enter either 1, 2 or 3";
while(true)
{
try
{
input = Convert.ToInt32(Console.ReadLine());
if (input == 0 || input > 3)
{
Console.WriteLine(errorMessage);
}
else
{
break;
}
}
catch(FormatException)
{
Console.WriteLine(errorMessage);
}
}
With this you your returned value "int input" will either be 0 or the number you entered and FormatExceptions caused by the string to convert containing symbols other than the digits 0-9 will be caught in the try/catch statement.

give this sample program a try:
static void Main(string[] args)
{
int stockbankInput = 0;
bool firstTry = true;
while(stockbankInput < 1 | stockbankInput > 3)
{
if(!firstTry)
Console.WriteLine("Error: Please enter either 1, 2 or 3");
firstTry = false;
Int32.TryParse(Console.ReadLine(), out stockbankInput);
}
}
First of all, don't use goto statements. They are considered bad practice, and it's like a blinding red light when reading your question - that's all I can focus on.
As per your question, an int or Int32 cannot be null. So you can't compare it to null. Give it a default value, and then check that.
This is a scenario where you don't need to check for an error, but just need to validate input. Use TryParse, which will set your out parameter if the parse is successful, or else set it to 0.
Next, you want to loop until you are given good input. An if statement is executed once, a loop will guarantee that when you leave it, your input will be valid.
Lastly, the firstTry is just a nice way to let the user know, after their first try, that they screwed up.

Related

Why does this code not work when I try to convert it

This is only a small piece of the code I'm trying to make work. The original code I wrote works but I want to make sure when the user inputs a number it is in fact a number.
Console.WriteLine("Give the number of A");
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
Console.WriteLine(Convert.ToDouble( A * A));
}
else
{
Console.WriteLine("Incorrecrt input");
}
The Console.WriteLine(Convert.ToDouble(A*A)); I only wrote to see if that will work and it doesn't. After the user inputs only a number I must use it in another equation for a final answer. The user must input 3 numbers.
For me, you should check is the input is a number that you can convert to double before converting it.
Console.WriteLine("Give the number of A");
var a = Console.ReadLine();
double number;
if (double.TryParse(a, out number))//double.TryParse takes a parameter and tries to convert it to double. If the convertion is successfull, sets the out parameter as result and returns true. If not, returns false. And you can use with other types like int.Tryparse(param, out outParam);
{
A = number;
}
else
{
//Not a number, show a message etc...
{
If you break this down:
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
}
What you're basically doing is:
Double A = Convert.ToDouble(Console.ReadLine());
Double dbl = Convert.ToDouble(A);
Boolean bl = char.IsNumber(dbl);
if (bl== correct)
{
}
So there's multiple things wrong here.
Firstly, you're trying to convert the user input without any sort of guarantee of success, so if someone typed "A" instead of a number it will throw an exception.
You should use TryParse and then if it's a valid conversion proceed.
Secondly, you're checking if a Double is a char that can be converted to a number. Obviously not because it's already a Double.
Thirdly, you're checking if a Boolean is equal to some variable called correct (which you haven't provided the definition of) so it's not clear if this is a valid comparsion.
EDIT:
This is what I would do:
bool validInput = false;
do
{
Console.WriteLine("Give the number of A");
string userInput = Console.ReadLine();
if (double.TryParse(userInput, out double result))
{
validInput = true;
Console.WriteLine(result * result);
Console.ReadLine();
}
else
{
Console.WriteLine("Invalid input. Please type a number.");
}
} while (!validInput);

C# Conversion of ReadKey() to int

I am new to C# and was told to create a Text-based Pokemon Battle Simulator, so in the code below, I have a method to get the user input and decide which nature the Pokemon get :
public static void NatureSelection(out int statIndex1, out int statIndex2)
{
Console.WriteLine("If you wish to have a neutral nature, Enter 0 in the next line, If not, enter any key to continue");
char holder = Convert.ToChar(Console.ReadKey());
statIndex1 = Convert.ToInt16(holder);
if (statIndex1 == 0)
{
statIndex2 = 0;
}
Console.WriteLine("Please Select A Nature For Your Pokemon By Entering The Number Beside The Stats That You Want To Increase ");
statIndex1 = Convert.ToInt16(Console.ReadKey());
while (!(statIndex1 > 0 && statIndex1 <=5))
{
statIndex1 = Convert.ToInt32(Console.ReadKey());
Console.WriteLine("Invalid Value,Please Try Again");
}
Console.WriteLine("Now Enter The Number Beside The Stats That You Want To Decrease ");
statIndex2 = Convert.ToInt32(Console.ReadKey());
while (!(statIndex2 > 0 && statIndex2 <= 5))
{
statIndex2 = Convert.ToInt16(Console.ReadKey());
Console.WriteLine("Invalid Value,Please Try Again");
}
}
However when I try to convert the readkey to int, it gives an error that says:
this line gives the errror:
char holder = Convert.ToChar(Console.ReadKey());
An unhandled exception of type 'System.InvalidCastException' occurred
in mscorlib.dll
Additional information: Unable to cast object of type
'System.ConsoleKeyInfo' to type 'System.IConvertible'.
Can someone explain what this mean and how I can fix it ?
Definitely this line Convert.ToInt16(Console.ReadKey()) cause the exception, because of a failure conversion, I suggest you to use like this:
int myNumber = (int)(Console.ReadKey().KeyChar);
Since Console.ReadKey() returns a ConsoleKeyInfo So that .KeyChar will give you the corresponding character value, which can easily be converted to an integer using implicit conversion. But this will give ascii values for characters as well.
Another option for you is TryParse, so that you can identify the conversion result also. that is the code will be like this:
int myNumber;
if (!int.TryParse(Console.ReadKey().ToString(), out myNumber))
{
Console.WriteLine("Conversion faild");
}
// myNumber holds the result

How do I make a loop that prompts the user to enter data every time they enter an invalid data type? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Console.WriteLine("Enter value for Monday : ");
milesMon = Console.ReadLine();
try
{
dblMon = double.Parse(milesMon);
}
catch
{
Console.WriteLine("You entered an invalid number - a default of 0 has been set");
dblMon = 0;
while (true) break;
Console.WriteLine("Enter value for Monday : ");
milesMon = Console.ReadLine();
In it's current state the code only prompts the user after they enter incorrect data the first time they do it, I would like to know how to make it so it happens every time.
-Thanks
You should use a do or while loop to keep repeating the prompt until a valid double is entered. You should also consider adding some form of exit keywords. Like if they enter "exit, quit, q" etc.. Have it terminate the app instead of loop back around. However being a console app, ctrl + c will close it regardless of what it's doing (it's the kill command) but not everyone knows that.
bool repeat = true;
var dblMilesMon = (double)0;
do
{
Console.WriteLine("Enter value for Monday : ");
var strMilesMon = Console.ReadLine();
if (!double.TryParse(strMilesMon, out dblMilesMon))
Console.WriteLine("You entered an invalid number - please enter a numeric value.")
else
repeat = false;
}while (repeat);
//do something with dblMilesMon
You can use TryParse() to convert the input string to double, it will return false if the conversion failed; based on that input you can prompt the user that whether the input is valid or not. and this will loop until the user enter Exit
string inputVal = "";
double inputDoubleVal;
while (inputVal == "Exit")
{
Console.WriteLine("Enter value for Monday : ");
inputVal = Console.ReadLine();
if (double.TryParse(inputVal, out inputDoubleVal))
{
//Process with your double value
}
else
{
Console.WriteLine("You entered an invalid number - a default of 0 has been set");
}
}
Basically you want to write a loop. While the input is invalid, prompt the user. So you should have a bool variable called valid to indicate whether the input is valid. And than a while loop like this:
while (!valid) {
//...
}
In the while loop, prompt the user. So the code looks like this:
bool valid = false;
int input = 0;
while (!valid) {
Console.WriteLine ("Prompt");
try
{
input = Convert.ToInt32 (Console.ReadLine ());
valid = true;
}
catch {}
}
Hope this helps!
You can use recursion to create your end-less loop without using a for or while.
Also, instead of a try-catch statement, better use a TryParse
Doc ref: https://msdn.microsoft.com/en-us/library/bb384043.aspx
public int readInput(){
int val = 0;
Console.WriteLine("Enter a valid int");
string enteredVal = Console.ReadLine();
bool result = int.TryParse(enteredVal, out val);
if(result)
return val;
Console.writeLine("Try again, only int values allowed");
return readInput();
}
int val = readInput();

Error happening when no value

I created a program that requires the user to input a value into a text box. I'm trying to have the text box default to 0 if there is no value put in by the user.
Currently, if there is no value put in and the calculation is attempted I get the error "input string was not in a correct format" error.
This is what I have:
cexp = int.Parse(currentexp.Text);
currentexp.Text = "";
I want to try to do something like this:
if (currentexp.text == "")
set cexp = 0
So if the text box is empty then I want to set the variable cexp to equal 0.
Solution 1 : You can use Conditional operator for setting the default value.
int cexp=(!String.IsNullOrWhiteSpace(currentexp.Text)) ? Convert.ToInt32(currentexp.text) : 0;
Solution 2: You can use int.TryParse() to perform the validation.
int cexp;
if(int.TryParse(currentexp.Text,out cexp))
{
//conversion successfull do some thing here
}
else
{
//conversion failed so do something here
}
You can use LINQ and conditional operator:
cexp = !currentexp.Text.All(char.IsDigit) ||
!currentexp.Text.Any() ? 0 : int.Parse(currentexp.Text)
This will set cexp to zero when currentexp.Text contains one or more non-digit characters.
It might be good to use int.TryParse for this, since the user is entering in data.
int cexp = 0;
if (!int.TryParse(textBox1.Text, out cexp))
{
var result = MessageBox.Show("An invalid entry was entered, do you want to use 0 instead?",
"Invalid Entry", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
//do stuff to continue here
//cexp will already be 0
}
else
{
//don't continue, they wanted to try again
}
}
This will default the value of cexp to 0, and if the user enters something invalid it will warn them (and still keep cexp at 0). If they put in a correct value, then cexp will be updated to what the user entered.
If you don't want to warn the user or anything, and just want to continue, this will work.
int cexp = 0; //default to 0
int.TryParse(currentexptextBox1.Text, out cexp); //try to get a number, if it fails, cexp will still be 0

How to validate a null input

the problem I'm having is to validate the input means putting it in a try catch which then wont pass the variable through and I'm getting this error:
Use of unassigned local variable 'MainMenuSelection'
I've validated using this method before but for some reason it's not working now, please help
//Take the menu selection
try
{
mainMenuSelection = byte.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("Please enter a valid selection");
}
switch (mainMenuSelection) //Where error is shown
Obviously user can input anything which would not be parsed as a single byte. Try out using Byte.TryParse() method which does not generate exception and just return status flag.
You can go further and add more analysis for an user input if needed:
// Initialize by a default value to avoid
// "Use of unassigned local variable 'MainMenuSelection'" error
byte mainMenuSelection = 0x00;
string input = Console.ReadLine();
// If acceptable - remove possible spaces at the start and the end of a string
input = input.Trim();
if (input.Lenght > 1)
{
// can you do anything if user entered multiple characters?
}
else
{
if (!byte.TryParse(input, out mainMenuSelection))
{
// parsing error
}
else
{
// ok, do switch
}
}
Also perhaps you just need a single character not a byte?
Then just do:
// Character with code 0x00 would be a default value.
// and indicate that nothing was read/parsed
string input = Console.ReadLine();
char mainMenuSelection = input.Length > 0 ? input[0] : 0x00;
A better method would be to use byte.TryParse(). It's made specifically for these types of scenarios.
byte b;
if (byte.TryParse("1", out b))
{
//do something with b
}
else
{
//can't be parsed
}
If you're just concerned about the input itself, you can use the Byte.TryParse Method and then handle the false boolean case instead.
byte mainMenuSelection;
if (Byte.TryParse(Console.ReadLine(), out mainMenuSelection)
{
switch(mainMenuSelection);
}
else
{
Console.WriteLine("Please enter a valid selection");
}

Categories