switch statement with nested if/else gives multiple outputs in c++

Viewed 163

I'm writing a pretty simple program for my first-year C++ class, where I utilize switch statements to get a correct output depending on what two numbers and what special character is used between them (adding, subtracting, multiplying, dividing). The program uses a nested if statement in the division case to check if the second number entered is zero, and a default statement if none of the correct special characters are used.

The problem lies in the fact that if the user divides by zero, or uses an incorrect symbol, the console will display the intended error, but also the result, when it's only supposed to show the message.

I understand why it's displaying both lines, but I don't know of any way to fix it. I'm not allowed to change the switch statement to an if statement, and I'm not allowed to use additional functions or arrays.

#include <iostream>
#include <iomanip>
#include <cstdlib>

using namespace std;

int main()
{
    char operatr;

    double operand1 = 0,
           operand2 = 0,
           result = 0;
    cout << "Enter a binary expression of the form: operand operator operand ";
    cin >> operand1 >> operatr >> operand2;
    cout << endl << endl
         << "C.S.1428.002" << endl
         << "Lab Section: L17" << endl
         << "10/14/20" << endl << endl;

    cout << fixed << setprecision(1);

    switch ( operatr )
    {
    case '+':
        result = operand1 + operand2;
        break;
    case '-':
        result = operand1 - operand2;
        break;
    case '*':
        result = operand1 * operand2;
        break;
    case '/':
        if ( operand2 == 0)
        {
            cout << operand1 << " " << operatr << " " << operand2 << " " << "Division by zero produces an undefined result" << endl;
            break;
        }
        else
        {
            result = operand1 / operand2;
            break;
        }
    default:
        cout << operand1 << " " << operatr << " " << operand2 << "  Encountered unknown operator." << endl;
        break;
    }

    cout << operand1 << " " << operatr << " " << operand2 << " = " << result << endl;

    system("PAUSE>NUL");

    return 0;
}
3 Answers

A simple solution would be to use a bool flag to signal a successful operation which would then be used as a condition to print the result:

//...

bool flag = true;

switch (operatr)
{
case '+':
    result = operand1 + operand2;
    break;
case '-':
    result = operand1 - operand2;
    break;
case '*':
    result = operand1 * operand2;
    break;
case '/':
    if (operand2 == 0)
    {
        cout << operand1 << " " << operatr << " " << operand2 << " "
             << "Division by zero produces an undefined result" << endl;
        flag = false;
    }
    else
    {
        result = operand1 / operand2;
    }
    break;
default:
    cout << operand1 << " " << operatr << " " << operand2 << "  Encountered unknown operator." << endl;
    flag = false;
    break;

}
if (flag)
    cout << operand1 << " " << operatr << " " << operand2 << " = " << result << endl;

//...

You could also use a try block, which I suspect can fall into the category of things you can't do, nonetheless it's worth taking a look at for future reference.

Or as suggested by @VladFeinstein in his answer just return from the switch in case an error occurs given that it's a one of execution.

In such a simple case, where there are no recovery from those input errors, why not just return 1; instead of break;?

Although the goto statement should generally not be used if there is a better alternative, in this case, I believe it is appropriate to use it. The alternatives would be code duplication or the introduction of an additional variable. See the other answer for a solution which avoids using goto by using an additional variable.

Here is my solution which uses goto:

int main()
{
    [...]

    default:
        cout << operand1 << " " << operatr << " " << operand2 << "  Encountered unknown operator." << endl;
        goto bad_input;
    }

    cout << operand1 << " " << operatr << " " << operand2 << " = " << result << endl;

bad_input:
    system("PAUSE>NUL");

    return 0;
}

Just remember not to make it a habit to use goto everywhere, as this is considered very bad programming style. Always look for better alternatives, such as for, while, do...while, break, continue, etc. That will make your code easier to read, both for yourself and for other people. There are only very rare cases in which the use of goto is appropriate.

Related