How to solve a IndexOutOfRange made by the user? - c#

I'm still new to programming, so every time i get an exeption i try to rewrite code so it is avoided. However in this case i see no way to work around it.
I have a textbox that the user uses to imput commands. The string(imput) is then split after the first space.
private void tbxMainImput_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
string commandText = tbxMainImput.Text.ToLower();
string[] commandTextSplitted = commandText.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
ReadTextboxImput(commandTextSplitted);
tbxMainImput.ResetText();
e.SuppressKeyPress = true; //anoying beep is removed :)
}
}
this splitted string commandTextSplitted is being used by a switch method ReadTextboxImput
private void ReadTextboxImput(string[] imput)
{
switch (imput[0])
{
//some other cases
case "attack":
StartCombat(imput[1]); //trows exeption if user only types one word
break;
}
}
If a player only types one word, imput[1] doesnt exist, and an IndexOutOfRange exeption is cast(as it should). However the exeption seems unavoidable. the player can type one word and press enter...
so ive been trying some things to check for the exeption and then break out of the code but it doesnt seem to work. The msdn website isn't realy beginners friendly, and all i found on stackoverflow where people asking to find where the error came from. witch i know.
So far i have tried:
case "attack":
if (imput[1] == null) //(imput[1] == system.IndexOutOfRange) doesnt make sense but i had to try
{
rtbOutput.AppendText("Yes yes. Attack nothing...");
break;
}
StartCombat(imput[1]);
break;
i made a method that uses try and catch that worked, but it just detected the error, i wasn't able to do anything with it(like return a false, or something)
Any help would be apreciated.

you can check if the array length is > 1 instead of imput[1] == null
if (imput.Length > 1){
rtbOutput.AppendText("Yes yes. Attack nothing...");
break;
}
StartCombat(imput[1]);
break;

Related

C# backspace on textbox creating errors immediately

I am creating an event where if someone types into a text box it will show an error using this code:
try
{
dblCostSqFt = double.Parse(txtCost.Text);
}
catch
{
MessageBox.Show("Error. You must enter valid numbers. Please correct.");
txtCost.Select();
return;
}
The issue with this is if I input a backspace it will throw that error message immediately I would like to make it to where that doesn't happen.
You're working with userinput here. Therefore i'd suggest to use Double.TryParse()
If you've got a string, and you expect it to always be a double (say, if some web service is handing you a double in string format), you'd use Double.Parse().
If you're collecting input from a user, you'd generally use Double.TryParse(), since it allows you more fine-grained control over the situation when the user enters invalid input.
With tryparse() your code will be something like this:
if (!double.TryParse(txtCost.Text, out var dblCostSqFt))
{
MessageBox.Show("Error. You must enter valid numbers. Please correct.");
txtExample.Select(0, txtCost.Text.Length);
return;
}
To make the example complete and address the issue one could simply check if the Text is not null or empty by using String.IsNullOrEmpty() making the whole code:
// makes sure your app isn't crashing upon backspaces.
if(string.IsNullOrEmpty(textCost.Text))
{
// Personally i'd indicate the user nothing is typed in (yet).
return;
}
if (!double.TryParse(txtCost.Text, out var dblCostSqFt))
{
// The user filled in something that can't be parse to doubles.
MessageBox.Show("Error. You must enter valid numbers. Please correct.");
txtExample.Select(0, txtCost.Text.Length);
return;
}
// All is great; Do stuff with dblCostSqFt.
Assuming you are using WPF for your UI without straying too far from what you have I would use something like below (as LarsTech suggested, use TryParse to test if the value can be converted). Note the if block surrounding the core code within the function, you can avoid execution entering the if block by checking if the key pressed was backspace. I also added a check for the enter key as many users would press the enter key to close the MessageBox, which would cause the event to trigger once again.
private void txtExample_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Back && e.Key != Key.Enter)
{
double dblCostSqFt = 0;
if (!double.TryParse(txtExample.Text, out dblCostSqFt))
{
MessageBox.Show("Error. You must enter valid numbers. Please correct.");
txtExample.Select(0, txtExample.Text.Length);
}
}
}
Never rely on exception handling to control the workflow of your application, exceptions have a ton of overhead and it is typically a bad practice in general.
You can accomplish the same thing in WinForms as well using the following...
private void txtExample_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode != Keys.Back && e.KeyCode != Keys.Enter)
{
double dblCostSqFt = 0;
if (!double.TryParse(txtExample.Text, out dblCostSqFt))
{
MessageBox.Show("Error. You must enter valid numbers. Please correct.");
txtExample.Select();
}
}
}
It looks like you are using WinForms because your textbox.Select function call does not supply any arguments, only WinForms supports an overload of the select function without any arguments.

Execute specific blocks of code based on which key on the keyboard is pressed

I am very new to the programming world and recently dove into c#. I don't want to waste your time so I'll get right to it. I wanted to create a program just to test my knowledge, and thought I could attempt to execute specific blocks of code based on which key on the keyboard is pressed by the user. I tried doing this by creating an event handler that contained if statements, but then realized I didn't know how to have the event handler active in the program.
For example, and as you can see in the below snippet, after the WriteLine in Line 5 lets say I wanted to raise the EventKeyPress event so that it waits for user input and reads the key they have pressed and reacts accordingly, how would I do that?
Again, I'm almost a complete beginner and have searched around for explanations about event handlers for hours and still can't wrap my head around what I am supposed to do or if I am even using the event handler correctly. Thanks in advance!
static void Main();
{
if (search == "Ball")
{
Console.WriteLine("Press enter to exit or backspace to return to the search bar")
// RIGHT HERE
}
else
{
Console.WriteLine("Sorry, I don't recognize {0}", search);
}
void EventKeyPress(object sender, KeyPressEventArgs e)
{
for (int i = 0; i < 1;)
{
if (e.KeyChar == (char)Keys.Enter)
{
// exit app
}
else if (e.KeyChar == (char)Keys.Back)
{
// go back to search
}
else
{
i = 0; // error
}
}
}
}
So, you're asking for something that involves Threading which is not a beginner thing to accomplish at all. The best way to do this for a beginner is to ask for a prompt, then accept as an input. For example.
Console.WriteLine("Hello, what's your name?");
string nameStr = Console.ReadLine();
Console.WriteLine($"Hello, {nameStr}");
You can then use your variable and apply it to an if/while or whatever kind of conditional.
if (nameStr == "Matt"){
//Do This Code.
}
Once you have that code, add a sequential method that will ask the user to return to the main menu or whatever you want it to do.
Main.ReturnMenu(); //Or whatever you want to use.

Something is wrong with my code

I am making a music maker program in C# (visual studio).
Here is my code:
int accCount = 0;
enum accidental { flat, sharp, none }
accidental thisAcc = accidental.none;
if (keyComboBox.SelectedItem.ToString().Length < 8)
{
MessageBox.Show("Please select a key!");
}
else switch (keyComboBox.SelectedItem.ToString())
{
case "C major - A minor":
accCount = 0; thisAcc = accidental.none;
break;
case "G major - E minor":
accCount = 1; thisAcc = accidental.sharp;
break;
...etc..
}
and so on...This all is included in postButton_click(postButton_Click(object sender, EventArgs e)
But when I click the button, an exception is shown (An unhandled exception of type 'System.StackOverflowException' occurred in Program.exe)And if I select "break", this line is selected:
object key(int count, accidental ac) (here is the cursor){
return key(0, accidental.none);
}
Does anyone know what is wrong?Sorry if this question is not specific enough, just tell me.
Well yes, look at this code (reformatted from your question for readability):
object key(int count, accidental ac)
{
return key(0, accidental.none);
}
That will just invoke the same method... which will invoke the same method... which will invoke the same method etc, until it runs out of stack space.
It's not clear what you intended to return from this method, but you need to stop recursing in this infinite way.
A stackoverflow means that you have some unbound recursion in your application. In English this essentially means you're calling a method again and again.
Can you see how you're calling your method key within itself?

Simple C# direction with declaring variables

I just started trying to learn C#. I've read probably 50 tutorials so far and thought I had a good understanding. Apparently I was wrong. I've been doing a lot of reading on msdn.microsoft.com's C# Programmer's Reference but it's seeming to not be the best source for tutorials.
I'm literally trying to accomplish the most simplest of tasks. Trying to understand variables, manipulation, and inputs. I come from web programming and want to turn a PHP script into a desktop application so I'm trying to learn the basics of C# and I think I might need to learn a different language instead.
Basically, I have a textbox and a button. When the button is clicked, I want to check the text in the textbox and see if it matches a certain string. Then display a message box with a message.
private void btnClick_Click(object sender, EventArgs e) {
if(txtCL.Text == "one") {
bool myTest = true;
} else {
bool myTest = false;
}
if(myTest == true) {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
Would really appreciate if someone could point me to better tutorials so I can learn quicker. Microsoft's documentation really hasn't taught me anything really.
I apologize for the stupid question, feel free to call me an idiot.
It's a scoping issue, myTest does not exist, at least not down there - you're creating it each time within the scope of each of your initial conditions. If you do:
bool myTest = false;
if(txtCL.Text == "one") {
myTest = true;
}
if(myTest == true) {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
Then you're specifying your boolean value, and setting it to false (which is the default value for a bool anyway, actually), then checking if your condition is met and reassigning it accordingly; it can then be evaluated to show your message box.
You could shorten this code yet more, an exercise for the reader. (:
you don't really need a bool variable, you can make it simplier:
private void btnClick_Click(object sender, EventArgs e)
{
if(txtCL.Text == "one")
{
MessageBox.Show("You entered the correct password.", "Important Message");
}
else
{
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
and if you need some tutorials, just google "C# beginner tutorials" or if you prefer video tutorials, you can take a look here.
if(...) {
bool myTest = true;
} else {
bool myTest = false;
}
// At this point in time 'myTest' is not a known variable.
// It's out of scope already s your next line will cause a compile error.
if(myTest == true) {
...
}
So you need to declare the variable in scope
bool myTest = false;
if(...) {
myTest = true;
}
// Now you can use the myTest variable
if(myTest) {
...
}
As you already pointed out, you don't need the variable at all, since this would work all the same
private void btnClick_Click(object sender, EventArgs e) {
if(txtCL.Text == "one") {
MessageBox.Show("You entered the correct password.", "Important Message");
} else {
MessageBox.Show("The password you entered is not correct.", "Incorrect Input");
}
}
You can read as many books as you like, but since you already have programming experience with PHP I'd suggest to get more hands on experience with C#. In parallel a book of course does not hurt. But I think the approach you are following (reading online, coding stuff) will pay off in the end. Give it some time. Practice. A lot.
i am assuming that nothing is happening when you click the button. is this true? if it is, put a break point at the line: if(txtCL.Text == "one") , run the app and click it. If you do not hit the break point then there is no linkage between the 'click' event and your code. Explore the button properties and you will see a way to make the linkage.
stick with it, i was a PHP guy and now a C# guy. It can be done.

Do loops and while loops

When I type in the word "Andrea" the program crashes. I am guessing, but I think it's because I am inside the loop and it doesn't know when to stop. If I am correct can you tell me how to get out of the loop. when I put a break in it tells me there is no loop to end.
private void button1_Click(object sender, EventArgs e)
{
do Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
while (textBox1.Text == "Andrea");
break;
do Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
while (textBox1.Text == "Brittany");
do Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
while (textBox1.Text == "Eric");
break;
MessageBox.Show("The spelling of the name is incorrect", "Bad Spelling");
You have textBox1.Text == "Andrea" and textBox1.Text == "Brittany" as your loop conditions, but you don't seem to be changing that value anywhere in the code. Therefore, you have an infinite loop which will result in your program crashing.
I'm not certain what your program is meant to be doing, but your options to break out of a loop are:
Use a break; statement to exit the loop.
Change your loop condition to something which can eventually result in false.
Change the textBox.Text property somewhere in the loop body.
Alternatively, you could use an if statement to check the condition once, and execute some code if that condition is true.
Edit:
I have done this with if statements but now i am looking to try doing the same thing with loops
no purpose just trying to learn how to program
In response to the above comments, I'll tell you how to replace an if statement with a loop. Just do it like so:
// Check the condition before executing the code.
while (textBox1.Text == "Andrea") {
// Execute the conditional code.
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
// We actually only want to execute this code once like an if statement,
// not while the condition is true, so break out of the loop.
break;
}
In your original post, you are using a do while loop rather than a while loop. You should keep in mind that the do while executes once for certain, regardless of whether its condition is true. It only checks the condition to see whether it should run additional times. The while loop, on the other hand, checks the condition before executing at all, which means you can substitute an if statement with it.
You should keep in mind that this is a bad practice. If you want to execute code depending on a certain condition, use an if statement. If you want to execute code repeatedly a certain number of times or while some condition is true, then use a loop.
At a glance, it looks like you have an infinite loop. As soon as you type in "Andrea" in textBox1 and click button1, it will perpetually update Commission.Text, not interrupting the thread to process any additional input.
The bigger question is, what the heck is this program supposed to be doing? And why is it doing it in a loop?
I suspect that by while you actually mean if. Otherwise, do you get an error message or exception when the application crashes? Can you wrap this function in a try/catch to see what the exception is?
Edit To clarify, try this method body:
private void button1_Click(object sender, EventArgs e)
{
try
{
if(textBox1.Text == "Andrea")
{
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
}
else if(textBox1.Text == "Brittany")
{
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
}
else
{
MessageBox.Show("The spelling of the name is incorrect", "Bad Spelling");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString(), "Bad Spelling");
}
}
}
}
Adding to what FacticiusVir said earlier, you can also do this in a switch statement (and since we're calculating the same commissions for each person, they can be combined:
private void button1_Click(object sender, EventArgs e)
{
switch(textBox1.Text)
{
case "Andrea":
case "Brittany":
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
break;
default:
MessageBox.Show("The spelling of the name is incorrect", "Bad Spelling");
}
}
If you want to do different commissions per person you need to split it (in the below Brittany is getting a different commission value now):
private void button1_Click(object sender, EventArgs e)
{
switch(textBox1.Text)
{
case "Andrea":
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
break;
case "Brittany":
Commission.Text = (Convert.ToDouble(textBox2.Text) / 15).ToString();
break;
default:
MessageBox.Show("The spelling of the name is incorrect", "Bad Spelling");
}
}
The do { x } while (y) construct runs x once, and then proceeds to run x continuously as long as y is true.
You're not having any success because you seem to be structuring it like this:
do
{
// This will just run over and over...
}
while (condition); // ...because this is always true.
break; // This isn't even in the loop!
In other words, the point where you're trying to add your break (based on a comment you left on another answer) is outside the loop, which is why your code is running indefinitely.
Now, it sounds like you're really just trying to use a do/while to emulate an if statement, presumably as a challenge to yourself. If that is the case, do yourself a favor and give up on that idea.
You cannot use a do/while loop to emulate an if condition, because do will always run at least once. The only way you could ensure that it runs exactly once under a specific condition (i.e., what if does) would be by embedding an if statement inside the do loop, which would defeat the purpose of the exercise.
That said, you can emulate an if with a while:
while (condition)
{
// Execute code once.
break; // Then just quit.
}
Looking at this one piece:
do Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
while (textBox1.Text == "Andrea");
...what do you expect to happen if textBox1.Text == "Andrea"?
What the program is doing is checking your comparison test, then if it's true, it does what is inside of the do / while block, then it checks the comparison test, then if it's true, it does what is inside of the do / while block, then it checks the comparison test, then if it's true, it does what is inside of the do / while block, then...
Get the point?
You use do / while loops if the condition is going to change inside the loop (or you explicitly break out of it).
What you want instead is to change it to something like
if( textBox1.Text == "Andrea" )
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
Just a guess, but as FacticiusVir says, you probably want to use conditionals instead of loops:
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "Andrea" || textBox1.Text == "Brittany")
{
Commission.Text = (Convert.ToDouble(textBox2.Text) / 10).ToString();
}
else
{
MessageBox.Show("The spelling of the name is incorrect", "Bad Spelling");
}
}

Categories