0

Hi I have this line in my main method:

std::copy(std::istream_iterator<Constituency>(inputFile), std::istream_iterator<Constituency>(), std::back_inserter(constits));

This parses a file into a vector. I have overwritten the std::istream << operator overload and am looking for ways to throw specific error messages if parsing fails. Here is the << operator overload:

std::istream& operator>> (std::istream& input, Constituency& constituency) {

    int num_neighbours;
    input >> num_neighbours;
    std::string name;
    std::vector<int> neighbours(num_neighbours);

    for(int i = 0; i < num_neighbours; i++) {
        try{
            input >> neighbours[i];
        } catch(...) {
            std::cout << "Error: Int Neighbour" << std::endl;
        }
    }
    try{
        input >> name;
    } catch(...) {
        std::cout << "Error: Expected String Name" << std::endl;
    }

    constituency = Constituency(name, neighbours);

    return input;
}

The error messages don't get printed out. How can I change this so that if a string is encountered where an int is expected it throws and error and vice versa.

Cesare
  • 71
  • 9
  • 2
    Segmentation fault is *not* a C++ exception and can't be caught by `try catch`. – Some programmer dude Apr 08 '20 at 12:47
  • @some[rpgrammerdude I dont want it to catch segmentation fault I want it to catch when it attempts to `input >> neighbours[i]` with a string when neighbours[i] is of type int – Cesare Apr 08 '20 at 12:50
  • not quite clear `neighbours[i];` is always an `int`. Perhaps you want to read input as string and first check if it is an integer or not – 463035818_is_not_an_ai Apr 08 '20 at 12:52
  • @idclev463035818 guess that could work and then throw an exception to the main method if its not an int? – Cesare Apr 08 '20 at 12:53
  • i think I understood what you want finally, there is a way to enable `cin` throw exceptions, but it is used so rare that I didnt find a good duplicate, this might help: https://stackoverflow.com/a/26187787/4117728 – 463035818_is_not_an_ai Apr 08 '20 at 12:56

1 Answers1

1

When an input operation fails, a "failbit" is set on the stream.

You can check for this with an "if" statement:

input >> neighbours[i];
if (!input) {
   std::cout << "Error: Int Neighbour" << std::endl;
}

Or:

if (!(input >> neighbours[i])) {
   std::cout << "Error: Int Neighbour" << std::endl;
}

However, as well as couting, you're also going to need to do something with that bad input. If you're not planning to just "return", you will have to skip a line, or skip some number of bytes, or do whatever it is that you think is appropriate. Also clear the error state with std::cout.clear(), otherwise no further input operations will succeed.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35