My goal is to have a simple piece of code that will raise an exception if input of non-int is entered.

My problem so far, is that I haven't been able to reach the catch block. I have read a little about bad_typeid, but do not know how to implement it.

#include <iostream>
#include <typeinfo>
using namespace std;

int isnum() //reads an int from user. Raises error if not of type int
{
  int temp;
  cout << "Please enter an int\n";
  cin >> temp;
  if (typeid(temp) != typeid(2)) //if input is not of same type as int
  {
    throw 4;
  }
  return temp;
}

int main()
{

  try
  {
    int temp = isnum();
  }
  catch (int e)
  {
    cout << "An exception occurred. Exception Nr. " << e << endl;
  }

  return 0;
}

Thanks.

Dani AI

Generated

As already hinted, using typeid here doesn’t help: the variable temp has type int at compile time, so typeid(temp) will always be typeid(int). The right approach is to validate what the user actually typed — either by checking the stream state after extraction, or by reading a line and parsing it. ’s loop (clear/ignore) is a fine way to recover from failed extractions; below is a robust alternative that parses a whole line and throws meaningful exceptions when the input is not a clean integer.

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

int read_int_line() {
  std::string s;
  if (!std::getline(std::cin, s)) throw std::runtime_error("no input");
  std::size_t pos = 0;
  int val;
  try {
    val = std::stoi(s, &pos);
  } catch (const std::invalid_argument&) {
    throw std::invalid_argument("not an integer");
  } catch (const std::out_of_range&) {
    throw std::out_of_range("integer out of range");
  }
  while (pos < s.size() && std::isspace(static_cast<unsigned char>(s[pos]))) ++pos;
  if (pos != s.size()) throw std::invalid_argument("trailing characters");
  return val;
}

Catch the standard exceptions (not plain int) so callers get useful messages:

try {
  int x = read_int_line();
} catch (const std::exception& e) {
  std::cerr << "Bad input: " << e.what() << '\n';
}

Notes and tips: std::stoi signals two distinct problems (invalid_argument vs out_of_range) so you can give better feedback. If you prefer stream-based parsing, use std::istringstream on the line and verify there’s nothing left after reading the integer. Prefer throwing/handling std::exception-derived types rather than raw integers, and avoid using exceptions for normal control flow — reprompting in a loop is usually the friendlier UX.

Recommended Answers

All 2 Replies

Hello,

Here is a source to do this task. Though it does not rely on a try,catch,throw block - it still gets the job done. I apologize if it does not meet your goal.

#include <iostream>
// this application by camelCase will resolve user input. If input must be translated into an ASCII table then the input was bad. Else, input is good.
using namespace std;

int main ()
{
    cout << "Please enter a number followed by a <return> or <enter>: ";
    double number;
    while (!(cin >> number))
    {
        // Enter this loop if input fails because of invalid data. Data will be evaluated on an ACSII standard.
        cout << "Sorry, I said enter a number!  Try again: ";
        cin.clear ();   // reset the "failure" flag

        // The input "cursor" is still positioned at the beginning of
        // the invalid input, so we need to skip past it.

        cin.ignore (1000, '\n');  // Skip to next newline or 1000 chars,
                                  // whichever comes first.  This is why
                                  // you have to follow the input with
                                  // <return> or <enter>.
    }
    cout << "OK, you entered " << number << "." << endl;
	getchar();
	getchar();
    return 0;
}

The result of a typeid expression is a std::typeinfo object representing the *type* of the expression.
Type of temp is an int, so typeid(temp) and typeid(4) both give typeid(int).

To check if the user entered an int or not, check the state of the stream after the attempted input. If an int could not be read, the stream would be put into a failed state.

if( !( cin >> temp ) ) throw 4 ;
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.