0

I have a function int read_int(const std::string& prompt) which reads a prompt message asking for a numerical value, the function then returns the value. The while loop inside the function will go on until the user enters a correct input in this case a number, if the user provides a non-numerical input the function prompts the user to enter another number. The problem I have is that when I input a non-numerical value it catches the error but the program terminates instead of prompting the user again. Any help to make this program work correctly would be appreciated, thank you.

#include <iostream>
#include <string>
#include <stdexcept>
#include <ios>
#include <limits>

int read_int(const std::string& prompt){

    std::cin.exceptions(std::ios_base::failbit); //Throws exception when an input error occurs
    int num = 0; // user input

    while(true){ //Loops until valid input

        try{

            std::cout << prompt;
            std::cin >> num;
            return num;
        }
        catch(std::ios_base::failure& ex){

            std::cerr << "Bad numeric string, try again" << '\n';
            std::cin.clear(); //Resets the error flag
            std::cin.ignore(std::numeric_limits<int>::max(), '\n'); //Skips current input line
        }
    }
}

int main() {

    std::string message = "Enter a number: ";

    read_int(message);

    return 0;
}
user4581301
  • 33,082
  • 7
  • 33
  • 54
Josue M
  • 23
  • 2
  • 2
    Sidenote: exceptions are slow and should only be used in exceptional circumstances. Using them to vet user input is generally a bad idea because humans screwing up is far from exceptional. – user4581301 Sep 27 '18 at 20:06
  • @user4581301 If anything it is the norm. You should plan that the users are going to screw up ;) – NathanOliver Sep 27 '18 at 20:11
  • It works for me. What compiler are you using? And what inputs produce the unwanted behavior? – user3738870 Sep 27 '18 at 20:11
  • Also works for me, and I can't see any error in the code. – john Sep 27 '18 at 20:12
  • This is what I get when I input a non-numerical value: terminate called after throwing an instance of 'std::ios_base::failure' what(): basic_ios::clear – Josue M Sep 27 '18 at 20:14
  • Change `catch(std::ios_base::failure& ex)` to `catch(const std::ios_base::failure& ex)`. That might be your issue. – NathanOliver Sep 27 '18 at 20:17
  • I wonder if `std::cin.clear();` is throwing. – john Sep 27 '18 at 20:18
  • @john [The official reference](http://www.cplusplus.com/reference/ios/ios/clear/) says it may throw.. – user3738870 Sep 27 '18 at 20:29
  • [this is most likely the answer](https://stackoverflow.com/questions/35088800/what-effect-would-lwg2349-have). I'm hesitant to close it as a dupe though. Maybe another gold badge holder can weigh in. – NathanOliver Sep 27 '18 at 20:30
  • `clear()` should never throw but I have a vague memory of one of the older standard libraries throwing when it shouldn't. In this code `clear(std::ios_base::failbit)` is the only thing that should make `clear` throw. @JosueM they way to find the answer is to run your code in a debugger which will show you where the exception is being thrown from. – Alan Birtles Sep 27 '18 at 20:38
  • @Alan Birtles I will try using the debugger thank you, I did read that other users ran the program and it worked fine, maybe this is something I can't control firsthand, maybe is a compiler issue. – Josue M Sep 27 '18 at 20:45
  • 1
    If you tell us which compiler (if it isn't a secret) we might be able to help... – Alan Birtles Sep 27 '18 at 20:46

0 Answers0