user8857966
user8857966

Reputation:

Comparing a text box's input to a variable

My program requires users to input answers into a text box to randomly generated questions. The questions have calculated answers which are stored in variables. Comparing the text box's input with that variable doesn't work properly, hence why I'm here.

enum elements { lithium, beryllium, sodium, magnesium };

public void Moles()
    {
        string elementName;
        int elementsLength = Enum.GetNames(typeof(elements)).Length;          
        double moles, mass, roundedMoles, Mr = 0;

        Random random = new Random();
        elementName = (Enum.GetNames(typeof(elements))[random.Next(0, elementsLength)]);
        mass = random.Next(1, 100);

        switch (elementName)
        {
            case "lithium":
                Mr = 7;
                break;
            case "beryllium":
                Mr = 9;
                break;
            case "sodium":
                Mr = 23;
                break;
            case "magnesium":
                Mr = 24;
                break;
        }

        moles = mass / Mr;
        roundedMoles = Math.Round(moles);

        label1.Text = ("How many moles in " + mass + "g" + " of " + elementName + "?");
        string input = textBox1.Text.ToString();

        if (input == roundedMoles.ToString())
        {
            MessageBox.Show("Good");
            textBox1.Clear();
        }
        else
        {
            MessageBox.Show("Bad");
            textBox1.Clear();
        }

private void button1_Click(object sender, EventArgs e)
    { 
        Moles();
    }

As you can see, the program will calculate a number of moles and round it to the nearest whole number. It's then stored in a variable, 'roundedMoles' - this variable is what's compared with the text box's input.

However, the message box will randomly show 'Good' or 'Bad' regardless of whether the input is correct or not. Bear in mind that this code works fine in a console application, so I don't know whether it's something I'm doing wrong or if it just doesn't want to work.

Sorry if this code isn't of a high standard. I'm not that good at programming.

Upvotes: 0

Views: 471

Answers (3)

John Wu
John Wu

Reputation: 52260

You have two problems.

Don't compare strings as numbers

When comparing numeric values, never compare string to string. Always convert to a numeric variable. Otherwise, "0.00" will not equal "0" and "1234 " (with a space at the end) won't equal "1234" (with no space). Also, you will run into serious trouble if you're working with a culture that uses , as the decimal point.

So, instead of this:

string input = textBox1.Text.ToString();
if (input == roundedMoles.ToString())
{
    MessageBox.Show("Good");
    textBox1.Clear();

Use something like this:

string input = textBox1.Text;
double inputAsDouble;
bool ok = double.tryParse(out inputAsDouble);
if (!ok)
{
    MessageBox.Show("Please enter a numeric value.");
    return;
}
if (inputAsDouble == roundedMoles)
{
    MessageBox.Show("Good");
    textBox1.Clear();

Don't compare floating point values as exact

When comparing floating point values, don't use ==. Instead, compute the difference and make sure it is below a certain tolerance. You have to do this because floating point variables are only approximations.

So instead of

if (inputAsDouble == roundedMoles)

use

const double Tolerance = 0.00001;
if (inputAsDouble - roundedMoles < Tolerance)

Upvotes: 1

Dave
Dave

Reputation: 3017

Ok so here is the answer...

The reason the console works is that you write to the console to ask the question. You then do console.Readline() this captures the input of the answer after they have seen the question.

On the forms version. You set the label to the question and immediately capture the text box value. The user has not had a chance to enter the answer, or its still the answer from the last time (hence why it randomly goes from "Good" to "Bad" because sometimes the answer is the same).

One simple way is make your variables at the top of the Moles() method, class variables on the form and then have 2 buttons with 2 methods one that gets the questions and sets your answer variables and then a second button then the user can press when they've entered their answer.

Check out this code paste https://www.pastebucket.com/564406

(You'll need button2 added to your form for this to work obviously)

edit: I've done a quick cut and paste of code there. You shouldn't just copy this and use it. Look what I've done and apply it properly and try and understand why it works

Upvotes: 0

NicoRiff
NicoRiff

Reputation: 4883

It seems that you might have a culture related problem down there. Always be careful when comparing Double values converted to String. The framework might be converting '1,5' to '1.5' depending on your regional settings. The first thing I would recomend you is not to compare as String but do it as Double. And if you do that, ensure that you will replace dots with comma or other way.

    if (Convert.ToDouble(input) == roundedMoles)
    {
        MessageBox.Show("Good");
        textBox1.Clear();
    }
    else
    {
        MessageBox.Show("Bad");
        textBox1.Clear();
    }

Upvotes: 0

Related Questions