!int.TryParse What am i doing wrong? - c#

I am making a pretty easy assignment.
I have a textbox and a button, if the user fills in a number it'll check if it's the correct number. Now I want to make sure that the user input is a number, if it's not then I want a message box to appear that ask to fill in a number. I made the following code but it's giving me an error when i fill in a letter in the textbox. Why?
private void guessBtn_Click(object sender, EventArgs e)
{
int number
number = Convert.ToInt32(numberTb.Text);
if (!int.TryParse(numberTb.Text, out number)){
MessageBox.Show("This isn't a number");
} else if (number == 3) {
MessageBox.Show("Correct!");
} else if (number < 3) {
MessageBox.Show("Incorrect, number must be higher");
} else {
MessageBox.Show("Incorrect, number must be lower");
}
}

TryParse doesn't just return whether the string can be converted to an integer. It actually does the conversion, and puts the result in the out parameter.
Therefore, you don't need a Convert.ToInt32 call before calling TryParse.
You got an exception because Convert.ToInt32 will throw an exception if the string is invalid. Basically, your program terminated because of Convert.ToInt32 before it even reaches TryParse.
So, remove the Convert.ToInt32 line.

Related

Separate the three-digit numbers in Windows form(C # ) and return them to the original state

In Windows Form (C #), I enter my number in the text box and separate the three digits with the following code (for better readability of the number). For example, the:
2500000 => 2,500,000
But I have a problem!
I want to do math operations (addition, multiplication, etc.) on my numbers. And I need to return my number to the first state (2500000) !?
please guide me
This is my code:
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
if (textBox1.Text == "")
{
textBox1.Text = "0";
}
textBox1.Text = long.Parse(textBox1.Text.Replace(",", "")).ToString("n0");
textBox1.SelectionStart = textBox1.Text.Length;
}
Since the Text property is a string, you will need to parse it to a number in order to make math operations. You can do this safely by calling the TryParse method.
if (long.TryParse(textBox1.Text, NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out var number))
{
// number is now of type long
number += number;
}
By the way, in your example you remove the commas by replacing them with an empty string, but then you put them back by calling .ToString("n0").

How do I Limit C# ReadKey entries?

I've been trying to find a way to do this but not had much luck so far.
Basically what I'm trying to do is limit the entries from the user so they can only enter 1 letter and 1 number using the Console.Readkey. So, for example, A1, E5, J9 etc. I want to avoid them entering like 55 or EE as this causes an error in my code. Is there an easy way to achieve this?
You need to write your own logic like you will check on every input value contains at least 1 number and 1 letter is true else false:
string value = Console.ReadLine();
//you can also check value.length and redirect if length greater than 2
if (value.Length > 2)
{
Console.WriteLine("Please enter correct value");
return;
}
if (value.Contains("Your Number"))
{
if (value.Contains("Your Letter"))
{
//your code goes here
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
This uses a GetChar method which requires that you pass a function to check whether the input is a character or a number. It won't allow you so proceed until a valid entry has been made.
using System;
class Program {
public static void Main (string[] args) {
string value = string.Empty;
// Get a character, using char.IsLetter as the checking function...
GetChar(ref value, char.IsLetter);
// Get a number, using char.isNumber as the checking function...
GetChar(ref value, char.IsNumber);
Console.WriteLine($"\nValue: {value.ToUpper()}");
}
// Get a character and append it to the referenced string.
// check requires that you pass a function reference for the required check.
public static void GetChar(ref string value, Func<char, bool> check) {
// Loop until the check passes.
while(true) {
char key = Console.ReadKey(true).KeyChar;
// If check passes...
if(check(key)) {
// Append the value
value += key.ToString().ToUpper();
// Print it...
Console.Write(key.ToString().ToUpper());
// Break out of the loop.
break;
}
}
}
}

Implementing a while loop to check for multiple exceptions in input validity

Sorry if this is a simple question; this is my first language and I'm trying my best to seek out and follow examples and explanations on this site and otherwise.
I've been trying to expand on a Microsoft C# tutorial program that creates "bank accounts." I'm trying to work on catching and handling exceptions, specifically by prompting the user to try again for a valid input.
I've come across this thread and many similar threads about running a loop while the input is invalid, and this example specifically using try/catch, which if I'm understanding correctly, is what I want to use here because I have a few lines of code that could throw multiple exceptions (it could be non-numerical or it could be negative). Following those and other examples, I can't figure out how to assign the initial balance input to a value that I can reference outside the loop (but still only within the CreateAccount method) once the input is valid.
I'm not sure what I have currently is working otherwise, but currently this code produces an error because initBalInput is left unassigned after the while loop, even though it's declared outside the loop and assigned in the try block.
public static void CreateAccount()
{
// Prompt for BankAccount constructor parameter {name} which is passed to BankAccount.Owner in constructor
Console.WriteLine("Name on new account: ");
string nameInput = Console.ReadLine();
decimal initBalInput;
bool valid = false;
while (valid == false)
{
try
{
Console.WriteLine("How much to deposit for initial balance: ");
initBalInput = Convert.ToDecimal(Console.ReadLine());
}
catch (ArgumentOutOfRangeException)
{
Console.WriteLine("Initial balance must be positive!");
valid = false;
continue;
}
catch (FormatException)
{
Console.WriteLine("Initial balance must be a number!");
valid = false;
continue;
}
valid = true;
}
// Create new instance "account" of type BankAccount and set its parameters
BankAccount account = new BankAccount(nameInput, initBalInput);
Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance.");
}
Instead of catching the exceptions, write the code that handles the invalid input.
public static void CreateAccount()
{
// Prompt for BankAccount constructor parameter {name} which is passed to BankAccount.Owner in constructor
Console.WriteLine("Name on new account: ");
string nameInput = Console.ReadLine();
string initBalInput = Console.ReadLine();
// try parse will check for invalid decimal values and also, positive values can be checked
if(decimal.TryParse(initBalInput, out decimal initBal) && initBal > 0) {
// Create new instance "account" of type BankAccount and set its parameters
BankAccount account = new BankAccount(nameInput, initBal);
Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance.");
} else {
Console.WriteLine("Invalid initial balance");
}
}
but currently this code produces an error because initBalInput is left unassigned after the while loop, even though it's declared outside the loop and assigned in the try block
The problem is that the compiler doesn't know if execution will ever reach the try block:
while (valid == false)
is evaluated at runtime. You and me both know that execution will enter at least once the while loop because valid is initially false but the compiler doesn't go into that type of analysis where variables are involved and therefore assumes execution might never enter the while loop and an unitialized initBalInput can be read.
That said, you should not get into the habit of using exepctions as control flow mechanisms. Exceptions should be exceptions, don't base the logic of your programs around exceptions. In your case, you should look into the method decimal.TryParse.
Also, always break up your problem into smaller problems. At the beginning, start small, make one liner methods that are obviously correct. It's very hard to write a bug in methods that are one or two lines long.
So what do you need?
A method that prompts the user for an input.
A method that validates the input
Something that asks the user to try again if the input is wrong.
Ok, numer one:
static string RequestUserInput(string message)
{
Console.Write(message);
return Console.ReadLine();
}
Number two: We already have it with decimal.TryParse(string, out decimal d). This method will return true if the input string can be parsed into a valid decimal number which will be assigned to d and false otherwise.
Number three:
public static decimal GetDecimalInput(string message)
{
decimal d;
while (true)
{
if (!decimal.TryParse(RequestUserInput(message), out d))
//tryparse failed, input is not a valid decimal number
Console.WriteLine("Initial balance must be a number!");
else if (d < 0) //try parse succeeded, we know input is a valid
// decimal number d but it might be negative.
Console.WriteLine("Initial balance must be positive!");
else
//we know inout is a valid non negative decimal number.
//break out of the loop, we don't need to ask again.
break;
}
return d;
}
And now, you put it all together:
var accountBalance = GetDecimalInput("How much to deposit for initial balance: ");
First, I have two articles on Exception handling that I consider required reading:
This one helps to classify the 4 common exception types - and if you should even consider catching them.
While this one goes into more details for good practices.
You should not be using convert, but parse. Or even better TryParse(). The exceptions on the string -> number conversion are the examples for vexing exceptions.
If there is no TryParse, I did once wrote a custom implementation of Int.TryParse() for someone still on Framework 1.1:
//Parse throws ArgumentNull, Format and Overflow Exceptions.
//And they only have Exception as base class in common, but identical handling code (output = 0 and return false).
bool TryParse(string input, out int output){
try{
output = int.Parse(input);
}
catch (Exception ex){
if(ex is ArgumentNullException ||
ex is FormatException ||
ex is OverflowException){
//these are the exceptions I am looking for. I will do my thing.
output = 0;
return false;
}
else{
//Not the exceptions I expect. Best to just let them go on their way.
throw;
}
}
//I am pretty sure the Exception replaces the return value in exception case.
//So this one will only be returned without any Exceptions, expected or unexpected
return true;
}
But that code looks like you want to have detailed information why it failed. At wich point you may have to write a detailed list of catch blocks.

How to I condition a text box for a string if it holds a integer

I'm currently having some issues with error checking on a textbox. It holds a variable (called Price) as Double. Its purpose is to take a number in, and when a button is clicked it adds it to a running total displayed in a different textbox.
Now I have an error when checking if the textbox is empty using:
!string.IsNullOrWhiteSpace(txtAddItem.Text)
However, I'm unsure of how to error check if a string or character other than a number has been entered. Any ideas are appreciated.
Method 1: RegEx
You should try to use a regular expression. Regular expressions (Regex in short) are used to match strings against patterns. For example, if you only want to allow integers:
Regex r = new Regex(#"^[0-9]+$")
The Regex class has an .IsMatch(string s) method, where s is the string you want to test against the pattern.
Method 2: try-catch and Parse()
Another way to do it, which might be a bit more beginner-friendly, is a try-catch block. (I am assuming your TextBox's name is TextBox1 and you store the sum value in a runningSum variable.)
try {
double x = double.Parse(TextBox1.Text);
runningSum += x;
catch (ArgumentException ax) {
//handle if it is not a number in the TextBox
}
Method 3: TryParse()
A more advanced version which combines try-catch and Parse() is using the double.TryParse() method which returns a true/false value based on whether conversion was successful or not.
double x;
if (double.TryParse(TextBox1.Text, out x)) {
runningSum += x;
} else {
//handle if it is not a number in the TextBox.
}
If the value needs to be a valid double you could use 'double.TryParse'. Something like:
if (double.TryParse(txtAddItem.Text, out double price) == false)
{
// Show error or clear textbox
}
else
{
// Value is valid, add to total
}
You can use Double.TryParse()
double number;
if (Double.TryParse(txtAddItem.Text, out number)) {
Console.WriteLine("'{0}' is a valid double: {1}", value, number);
} else {
Console.WriteLine("Unable to parse '{0}' as a valid double", value);
}

Textbox Contains Only Certain Characters C#

I have a simple WinForms app that generates random numbers based on the maximum number entered. For the maximum number text box I already have code that checks the 'key press' input so that numbers and "." are the only characters input. Hence, decimal numbers are allowed. However, I also want to check that the text box doesn't just contain 0's and "." An outline of my code is shown below:
if(txbInput.Text.Length == 0)
{
validation fails
}
else if(txbInput Contains just 0s and .)
{
validation also fails
}
else{
do maths
}
What would be the correct way to do this in the 'else if' statement?
Why don't you use Decimal.TryParse or Double.TryParse instead?
decimal d;
if(!decimal.TryParse(txbInput.Text, out d))
{
// validation fails, output an appropriate message to the user
}
else if (d == 0m)
{
// validation fails, output an appropriate message to the user
}
Try to use a NumericUpDown control instead of TextBox. This will eliminate validation and parsing in your code, except for comparing its Value property with zero.
Remark: To use this control for editing a real numbers, set an appropriate values for the properties DecimalPlaces and Increment.
you could use the KeyPressEvent for that...
like
private void tb1_KeyPressed(object o,KeyPressEvents e)
{
if(/*insert your validation here*/)
{//valid case
e.Handled=false;
}
else
{//false case
e.Handled=true;
//inform user about mistake
}
}
if you set Handled =true then nothing will happen after a key got pressed. Through that you can surpress keys in a textbox

Categories

Resources