I have a very simple scenario that looks like
std::ifstream file("myfile.txt");
std::string discard;
int num;
file >> discard >> num; // to consume e.g. HEADER 55
Despite all of its other foibles, fscanf
has a feature that is useful to me and I don't see obviously being available in ifstream
. Quoting cppreference,
The format string consists of non-whitespace multibyte characters except
%
: each such character in the format string consumes exactly one identical character from the input stream, or causes the function to fail if the next character on the stream does not compare equal.
Other than >>
to a string, comparing to a known value and aborting the operation if the comparison fails, is there something akin to a >> std::expect("HEADER")
that would more directly express this case? (In my imagination this is "not so crazy" because other >>
input operations already do this on other failure types such as integer parse failure).
Other than
>>
to a string, comparing to a known value and aborting the operation if the comparison fails, is there something akin to a>> std::expect("HEADER")
that would more directly express this case?
There is nothing native in the standard library for that exact purpose, but you can easily write your own I/O manipulator to handle it, eg:
class expect_t {
public:
expect_t(const std::string_view &value) : m_value(value) {}
friend std::istream& operator>>(std::istream &is, const expect_t &expected) {
std::string s;
if (is >> s) {
if (expected.m_value != s) {
is.setstate(std::ios_base::failbit);
}
}
return is;
}
private:
std::string_view m_value;
};
expect_t expect(const std::string_view &value) { return expect_t{value}; }
Then you can do this:
std::ifstream file("myfile.txt");
int num;
if (file >> expect("HEADER") >> num) { // to consume e.g. HEADER 55
// OK, use num as needed...
} else {
// failed
}