0

So not the overloaded operator itself, but in its function body (Whatever you call it). For example:

std::istream& operator>>(std::istream& in, std::vector<queryPoint>& queryPoints)
{
    queryPoint point;
    in >> point.x2; 
    in >> point.y2; 
    in >> point.name;

    queryPoints.push_back(point);
    return in;
}

Here is a snippet of code that will take in input from an external file, and will pass the first three inputs into an integer, another integer, and a string. I would like to catch an error if the file inputs a string, or a char, or any input error, into my point.x2 or point.y2, if that makes sense. How could I do this? I would also like to send out an error message, and terminate the program. Do I also have to reset the input stream, like I have to do with std::cin.clear() and std::cin.ignore(10000, '\n')?

Thanks in advance.

Leo C
  • 9
  • 1
  • My standard advice is read all input in as strings. Then parse the string to make sure it is as expected and if not, then raise an error however you want to. If it is then convert the string into the type you need. – NathanOliver Oct 28 '20 at 20:54
  • How can I make sure that the string is not holding integer? – Leo C Oct 28 '20 at 20:56
  • Make sure there are no numeric characters in the string? – NathanOliver Oct 28 '20 at 20:57

1 Answers1

0

You can check whether "extraction" from the stream succeeded by evaluating the returned std::istream object as a boolean. If the "extraction" failed, it will evaluate to false.

To return an error message, you should throw an exception. That way whoever calls your operator>> can wrap it in a try-catch block if they want to. If they don't you'll program will exit with the message you've constructed the exception with.

So, you could do it like this:

#include <stdexcept>

std::istream & operator>> (std::istream & in, queryPoint & obj) {
  if (not (in >> obj.x2)) { throw std::runtime_error("Failed to extract x2"); }
  if (not (in >> obj.y2)) { throw std::runtime_error("Failed to extract y2"); }
  if (not (in >> obj.name)) { throw std::runtime_error("Failed to extract name"); }

  return in;
}

It's then up to you to use this in a function which gets a whole vector of these queryPoint objects from a stream.

You don't have to do anything with the stream. When the in object eventually goes out of scope, due to your program terminating, the stream will be properly closed.

AVH
  • 11,349
  • 4
  • 34
  • 43