-1
#include <iostream>
using namespace std;
int main(){
    char opp;
    double num1,num2;
    bool cont=true;
    while (true){
        cout<<"Enter first number"<<endl;
        cin>>num1;
        cout<<"Enter operator"<<endl;
        cin>>opp;
        cout<<"Enter second number"<<endl;
        cin>>num2;
        if (opp=='+'){
            cout<<num1<<opp<<num2<<"="<<num1+num2<<endl;
        }        
        else if (opp=='-'){
                cout<<num1<<opp<<num2<<"="<<num1-num2<<endl;
                
            }
            else if (opp=='*'){
                cout<<num1<<opp<<num2<<"="<<num1*num2<<endl;
                
            }
            else if (opp=='/'){
                cout<<num1<<opp<<num2<<"="<<num1/num2<<endl;
                
            }
            else{
                cout<<"INVALID OPERATOR"<<endl;
            }
    }
        
    return 0;
}

I am new to c++ and have written a basic calculator, now I wanted to make the main function loop forever. But when I do this it just keeps looping through the prints and doesn't let the user input anything.

hirok
  • 3
  • 3
  • 1
    Can you give an example of what you're entering that causes this behavior? – Nathan Pierson Jan 21 '22 at 22:05
  • this is a good article to read: https://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input – Asphodel Jan 21 '22 at 22:07
  • @NathanPierson Pierson I have just tried running the compiled file, and it runs fine, but when I run the code in visual studio code, it doesn't wait for inputs and just prints the line including the 'invalid input' – hirok Jan 21 '22 at 22:10
  • Compilation means a program is syntactically correct. That the grammar is valid. The correctness of grammar unfortunately says very little about the correctness of logic. One thing you can do to confirm correctness of logic is to always consult and act on return codes and other status information provided by functions. For example, `cin>>num1;` tries to read user input into a `double` and makes no attempt to confirm that a double was actually read. If you do not detect and handle errors, those errors will become bugs. – user4581301 Jan 21 '22 at 22:19
  • @Asphodel thank you this works :) – hirok Jan 21 '22 at 22:20
  • You could use a _special_ operator for quitting your main loop (e.g. `q`) [Demo](https://godbolt.org/z/szoYjEj3e). Though this is not your main problem; as others said, 1) you should check your inputs for errors, and 2) `std::cin` can be especially problematic for reading input; better use `std::getline` to read your inputs into a string, then process that string (doing the error checking there). – rturrado Jan 21 '22 at 22:23

3 Answers3

0

Use std::getline() as suggested by @rturrado.

std::string str;
while (std::getline(std::cin, str))
{
    if (str.empty() || str[0] == 'q' || str[0] == 'Q')
        break;
    // validate and process a line here
}

More details here: https://www.boost.org/doc/libs/1_66_0/libs/spirit/example/qi/compiler_tutorial/calc4.cpp

Kukanani
  • 718
  • 1
  • 6
  • 22
0

I would suggest using getline to overcome this problem, you can do something like:

std::string str;
while(true) {
// get the first input 
std::getline(std::cin, str)
if (!str.empty())
        // cast str to double or keep it
 // you got the idea
 } 
Mostafa Wael
  • 2,750
  • 1
  • 21
  • 23
0

You can get the input and store it in std::string and then convert it to anything that is needed (like double, char, etc).

Also, it's better to use a switch statement instead of that if-else if-else chain.

With a bit of refactoring (and keeping things as simple as possible):

#include <iostream>
#include <string>
#include <stdexcept>


struct OperationData
{
    double num1;
    double num2;
    double result;
    char opp;
};

double get_input_double( )
{
    std::string num_str;
    std::getline( std::cin, num_str );
    return std::stod( num_str );
}

void printResult( const OperationData& operation_data )
{
    std::cout << operation_data.num1 << ' ' << operation_data.opp
              << ' ' << operation_data.num2 << " = " << operation_data.result << '\n';
}

int main( )
{
    while ( true )
    {
        std::cout << "Enter e or E to exit the program, or any other character to continue: ";
        std::string isExiting { " " };
        std::getline( std::cin, isExiting );
        if ( isExiting[0] == 'e' || isExiting[0] == 'E' ) { break; }

        std::cout << "Enter the first number\n";
        double num1 { };

        try
        {
            num1 = get_input_double( );
        }
        catch ( const std::invalid_argument& ) { std::cout << "Invalid argument\n"; continue; }
        catch ( const std::out_of_range& ) { std::cout << "Entered value out of range\n"; continue; }

        std::cout << "Enter the operator\n";
        std::string opp_str { " " };
        std::getline( std::cin, opp_str );
        const char opp { opp_str[0] };

        std::cout << "Enter the second number\n";
        double num2 { };

        try
        {
            num2 = get_input_double( );
        }
        catch ( const std::invalid_argument& ) { std::cout << "Invalid argument\n"; continue; }
        catch ( const std::out_of_range& ) { std::cout << "Entered value out of range\n"; continue; }

        switch ( opp )
        {
            case '+' :
                printResult( { num1, num2, num1 + num2, opp } );
                break;
            case '-' :
                printResult( { num1, num2, num1 - num2, opp } );
                break;
            case '*' :
                printResult( { num1, num2, num1 * num2, opp } );
                break;
            case '/' :
                printResult( { num1, num2, num1 / num2, opp } );
                break;
            default :
                std::cout << "INVALID OPERATOR\n";
        }
    }
}

Sample input/output:

Enter e or E to exit the program, or any other character to continue:
Enter the first number
45.5
Enter the operator
/
Enter the second number
3
45.5 / 3 = 15.1667
Enter e or E to exit the program, or any other character to continue: E

Note: If the input is not convertible to double, std::stod will throw a std::invalid_argument or a std::out_of_range exception and in the above code there are try-catch blocks to handle the exceptions. An appropriate message will be displayed and the program will jump to the beginning of the loop to start the process from the first step whenever an exception is thrown.

digito_evo
  • 3,216
  • 2
  • 14
  • 42