Search code examples
c#stringinputformatexceptionunhandled

Why am I getting a FormatException was unhandled error?


I have created a program, and a extensive test of it, I'm getting a error that says "FormatException was unhandled, Input string was not in a correct format". The problem occurs when I leave either of the text boxes blank and press the 'Finished' button but it works fine if I enter anything below 0 or above 59 - which is the number range I want to allow. What could I do so I don't receive this error when the boxes are blank? This is my code behind 'btnFinished':

   private void btnFinished_Click(object sender, EventArgs e)
    {
        if (lstCyclists.SelectedIndex >= 0)
        {
            Cyclists currentCyc = (Cyclists)lstCyclists.SelectedItem;
            //Decalre the minsEntered and secsEntered variables for txtMins and textSecs
            int minsEntered = int.Parse(txtMins.Text);
            int secsEntered = int.Parse(txtSecs.Text);

            try
            {
                //If the status of a cyclist is already set to Finished, show an error
                if (currentCyc.Finished.ToString() == "Finished")
                {
                    MessageBox.Show("A time has already been entered for this cyclist");
                }
                else
                {
                    //if a minute lower than 0 or greater than 59 has been entered, show an error
                    if (minsEntered < 0 || minsEntered > 59)
                    {
                        MessageBox.Show("You can only enter a minute up to 59");
                    }
                    //if a second lower than 0 or greater than 59 has been entered, show an error
                    else if (secsEntered < 0 || secsEntered > 59)
                    {
                        MessageBox.Show("You can only enter a second up to 59");
                    }
                    else
                    {
                        //otherwise, set the status to finished and update the time
                        currentCyc.Finished = "Finished";
                        currentCyc.FinishedHours(Convert.ToInt32(txtHours.Text));
                        currentCyc.FinishedMins(Convert.ToInt32(txtMins.Text));
                        currentCyc.FinishedSecs(Convert.ToInt32(txtSecs.Text));
                        //pass the parameter to the scoreboard class to display it in lblCyclistsFinished
                        lblCyclistsFinished.Text += "\n" + finishLine.Scoreboard(currentCyc);
                        //add to the number of cyclists finished
                        Cyclists.NumFinished++;
                        lblnumFinished.Text = Cyclists.NumFinished.ToString();
                        //update the details box
                        DisplayDetails(currentCyc);
                        txtHours.Clear();
                    }
                }
            }
            catch
            //make sure all the time fields have been entered, otherwise show an error message
            {
                MessageBox.Show("Please ensure all time fields have been entered");
            }
        }
        else
            //make sure a cyclist has been selected when pressing "Finished", otherwise show an error message
        {
            MessageBox.Show("You must select a cyclist");
        }
    }

Solution

  • Well, look at these lines:

    int minsEntered = int.Parse(txtMins.Text);
    int secsEntered = int.Parse(txtSecs.Text);
    

    What do you expect those to return when the text boxes are blank?

    Simply don't call int.Parse for empty textboxes. For example:

    int minsEntered = txtMins.Text == "" ? 0 : int.Parse(txtMins.Text);
    // Ditto for seconds
    

    Of course, this will still go bang if you enter something non-numeric. You should probably be using int.TryParse instead:

    int minsEntered;
    int.TryParse(txtMins.Text, out minsEntered);
    

    Here I'm ignoring the result of TryParse, and it will leave minsEntered as 0 anyway - but if you wanted a different default, you'd use something like:

    int minsEntered;
    if (!int.TryParse(txtMins.Text, out minsEntered))
    {
        minsEntered = 5; // Default on parsing failure
    }
    

    (Or you can show an error message in that case...)