White Dwarf
White Dwarf

Reputation: 189

problem with I/O exception in c++ ("cin" statement)

In the following program:

int main(){

    std::cout<<"enter numbers to be divide"<<std::endl;
    int a,b,c;

    while(true){
        try{
            if(!(std::cin>>a>>b)){
                throw std::invalid_argument("please enter proper interger");
            }

            if(b==0){
                throw std::runtime_error("please enter enter nonzero divisor");
            }
            c=a/b;
            std::cout<<"quotient = "<<c<<std::endl;
        }
        catch(std::invalid_argument e){
            std::cout<<e.what()<<"\ntry again?enter y/n";
            char c;
            std::cin>>c;
            if(c=='n'||c=='N') break;
        }
        catch(std::runtime_error e){
            std::cout<<e.what()<<"\ntry again?enter y/n";
            char c;
            std::cin>>c;
            if(c=='n'||c=='N') break;
        }
    }
    return 0;
}

I am using two kinds of exception.Program is working perfectly when it throws "runtime_error" exception but goes into infinite loop when encounter "invalid_argument" exception. Actually there is problem in "cin>>c" statement in catch-block but can not figure out, why this is happening.

Upvotes: 1

Views: 1665

Answers (2)

spraff
spraff

Reputation: 33385

You can play with exception masks, you might find a preferable way to handle errors.

Upvotes: 0

NPE
NPE

Reputation: 500167

When std::cin>>a>>b encounters a non-numeric character, two relevant things happen:

  • the offending character is not consumed;
  • the fail bit of std::cin is set.

The latter prevents all further reads from std::cin from succeeding. This includes those inside your invalid_argument catch block and those inside subsequent iterations of the loop.

To fix this, you need to clear the state of std::cin and to consume the offending character. This is explained very well in the following answer pointed out by KennyTM: C++ character to int.

Upvotes: 3

Related Questions