As others have pointed out, the input operator for int already does the conversion from a sequence of digits to an int. However, this conversion also does something which may or may not be the Right Thing: the formatted input operators do skip leading whitespace, not distinguishing between different sorts of whitespace. That is, if one line contains fewer values than expected, the stream will happily read them from the next line! Whether this the correct behavior or not depends on the exact use. Since the question specifically mentioned the format containing four values on each line, I'll assume that it is not OK to have fewer than 4 values on each line.
Preventing the input operators from automatically skipping whitespace can be done using std::noskipws. Once this is applied it become necessary to skip the whitespace explicitly, though. Skipping whitespace but no newlines can be done using a custom manipulator:
std::istream& skipspace(std::istream& in) { std::istream::sentry cerberos(in); if (in) { std::istreambuf_iterator<char> it(in), end; while (it != end && *it != '\n' && std::isspace(static_cast<unsigned char>(*it))) { ++it; } } return in; }
With a manipulator like this, it is fairly straight forward to implement reading a line of values and to fail if there are not enough values:
- Turn off automatic skipping of whitespace.
- Skip leading whitespace using
std::ws to get rid of the previous line end and possible leading whitespace on the line. - Read each value, skipping only non-newlines between the objects.
That is, an input operator for the class Numbers would look like this:
std::istream& operator>> (std::istream& in, Numbers& numbers) { int first, second, third, fourth; if (in >> std::noskipws >> std::ws >> first >> skipspace >> second >> skipspace >> third >> skipspace >> fourth) { numbers = Numbers(first, second, third, fourth); } return in; }
std::vector<std::vector<int>>could be used to store the numbers just as they are in the file, and then afterwards use those values for creating your objects