Thread: std::cin exception handling

  1. #1
    Registered User ex-mortis's Avatar
    Join Date
    Mar 2012
    Posts
    37

    std::cin exception handling

    Code:
    #include <iostream>
    #include <fstream>
    #include "MoneyManagement.h"
    
    int main ()
    {
        std::ifstream iMoney("money.txt");
    
        if(!iMoney){
            std::cout<< "Error opening file.\n\n";
        }
    
        double a;
        iMoney >> a;
    
        while(true){
            std::cout << "What would you like to do?\n\n1. Update balance\n2. Print balance\n3. Exit\n\n";
    
            int x;
            try{
                std::cin >> x;
                if(!std::cin){
                    throw "Error: Please input an integer";
                }
            }
            catch (const std::string& msg){
                std::cout << msg << std::endl;
            }
            MoneyManagement updM;
            switch (x) {
                case 1:
                    std::cout << "\nInput new amount:\n";
                    double upd;
                    std::cin >> upd;
                    std::cout << std::endl;
                    a = upd;
                    updM.saveData(a);
                    break;
                case 2:
                    std::cout << "Current balance: " << a << std::endl;
                    break;
                case 3:
                    return 0;
            }
        }
    }
    I'm a complete noob at exception handling and barely understand how to do it properly. The !std::cin idea is something I got while searching online, but for some reason it just won't work in my program. It compiles correctly but if I input a string the program crashes and returns 3. Does anybody know what I'm doing wrong?

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    That's not at all an appropriate use of exceptions.

    Your problem though comes from the simple fact that the `const char *' which you've thrown is not a `const std::string &' that you catch.

    It isn't crashing by the way; it is just calling `std::terminate' because you've allowed an exception to propagate "too high".

    Soma

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Throwing an exception to yourself is insane.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User ex-mortis's Avatar
    Join Date
    Mar 2012
    Posts
    37
    Quote Originally Posted by phantomotap View Post
    O_o

    That's not at all an appropriate use of exceptions.

    Your problem though comes from the simple fact that the `const char *' which you've thrown is not a `const std::string &' that you catch.

    It isn't crashing by the way; it is just calling `std::terminate' because you've allowed an exception to propagate "too high".

    Soma
    So I shouldn't check for errors? Passing a string into std::cin >> *int* yields weird behavior. What I want is to reject all types save for integers. How would I go about that? I've tried catching a 'const char *' and nothing changed.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I suggest if statements, not exceptions.

    Jim

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    So I shouldn't check for errors?
    O_o

    You don't use exceptions to check for errors. Actually, you can't use exceptions to check for errors.

    [Edit]
    Before anybody dwells to long on that, I'm talking about the fact that errors must be transformed into exceptions.
    You can obviously `catch' exceptions once an error has been so transformed.
    [/Edit]

    You use exceptions to propagate an error and the context of that error to the most reasonable point in the "call chain" to handle an error.

    You are using an `if' to check for an error; when an error occurs you transform that error into an exception which you `catch' locally.

    Code:
    if(!(std::cin >> x)){
        std::cout << msg << std::endl;
    }
    I've tried catching a 'const char *' and nothing changed.
    Then you didn't make the right change, and because you didn't post your latest code I have no idea what you may have done wrong.

    Soma
    Last edited by phantomotap; 07-11-2012 at 05:45 PM.

  7. #7
    Registered User ex-mortis's Avatar
    Join Date
    Mar 2012
    Posts
    37
    Well seeing as I don't know how to use exceptions I went back to the if statement method (which is what I tried to do first anyway and failed). It looks like this:

    Code:
            int x;
            if (std::cin >> x){
            }
            else {
                std::cout << "Error: Please input an integer.\n\n";
            }
            std::cin.ignore();
    This still causes an infinite loop of couts when I enter a non-int.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You must clear() the error flags before your cin.ignore(), plus you should ignore() more than just one character. What happens if the user entered multiple characters?

    Jim

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    This still causes an infinite loop of couts when I enter a non-int.
    I know you are new; I appreciate that.

    You need to appreciate this: you can't really start exploring concepts until you have built a firm foundation.

    Please stop trying to "throw code at the compiler and see what sticks" until after you have the basics in your mental toolbox.

    It causes an infinite loop because you haven't told the `std::cin' object that you need the error state cleared.

    Soma

  10. #10
    Registered User ex-mortis's Avatar
    Join Date
    Mar 2012
    Posts
    37
    Quote Originally Posted by phantomotap View Post
    I know you are new; I appreciate that.

    You need to appreciate this: you can't really start exploring concepts until you have built a firm foundation.

    Please stop trying to "throw code at the compiler and see what sticks" until after you have the basics in your mental toolbox.

    It causes an infinite loop because you haven't told the `std::cin' object that you need the error state cleared.

    Soma
    I'm not just trying random stuff until something works, I just don't have a clue how cin works yet (though I have a vague idea now). This is actually the first program I've written in several weeks because I've been focusing on reading C++ and building a repertoire. But point taken; being bold and making mistakes is the best way to learn however.

    Clearing the error state fixes it for the most part, but now the program stops completely until I've passed in 5 or so values, at which point it finally goes back to the "menu". I think it has something to do with cin.ignore() but I'm not sure. Here's the updated code:

    Code:
            int x;
            if (std::cin >> x){
            }
            else {
                std::cout << "Error: Please input an integer.\n\n";
                std::cin.clear();
                std::cin.ignore(10);
            }
    Last edited by ex-mortis; 07-11-2012 at 06:03 PM.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    But point taken; being bold and making mistakes is the best way to learn however.
    O_o

    No. That's how you wind up meeting "Mr. Friendly" and get "popcycled"

    For mistakes to be valuable you must learn from them which means not repeating them over and over.

    Now, I suppose, is as good a time as any to tell you that the forum software remembers posts.

    So, as I said, stop just throwing code at your compiler until you learn the basics.

    Soma

    Simple password system

  12. #12
    Registered User ex-mortis's Avatar
    Join Date
    Mar 2012
    Posts
    37
    I just read through the "Why does my program enter an infinite loop if the user inputs invalid data?" entry that was linked to me and was better able to understand it now than before. So, now my program works perfectly. Thanks for the replies Soma and Jim (could have done with less condescension though).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exception errors OR exception handling :S
    By cruiser in forum C++ Programming
    Replies: 4
    Last Post: 09-02-2011, 05:30 AM
  2. signal handling and exception handling
    By lehe in forum C++ Programming
    Replies: 2
    Last Post: 06-15-2009, 10:01 PM
  3. exception handling
    By jbook in forum C++ Programming
    Replies: 7
    Last Post: 10-19-2007, 01:42 PM
  4. CIN and exception handling
    By OldSchool in forum C++ Programming
    Replies: 4
    Last Post: 05-14-2006, 05:02 PM
  5. Exception handling
    By Hankyaku in forum C++ Programming
    Replies: 2
    Last Post: 04-06-2003, 08:25 AM