Reputation: 420
Basic question here. I'm reading a file, and writing values from the file to unsigned ints, like so:
// The essential stuff
std::ifstream infile(filePath.c_str());
std::getline(infile, line);
std::istringstream in(line);
char type;
in >> type;
unsigned int x, y, z, w;
in >> x >> y >> z >> w; // My question relates to this here.
Here's the issue: getting the x, y, z and w values works fine, except I'd like for w
to be optional. So a line might contain f 0 1 2 3
(the type, plus 4 values), or it might only contain f 0 1 2
.
Naively, I was hoping w
would just equal EOF or something similar, but alas, such is not the case.
I could count the spaces in the line, and use that to check if w
exists or not. Or I could use peek
to check if the line has ended after z or not, but it's not quite that simple, seeing as I'd also like to ignore whitespaces (i.e. there might be 10 spaces between the z and w characters, and that should still be valid). So solutions definitely exist, but I'm wondering if there's... some neater way? Something like this, perhaps?
writeTo(w);
if w is junk
disposeOf(w);
Upvotes: 0
Views: 167
Reputation: 153792
When an input operator fails it sets the stream to a failure state, i.e., it sets the status flag std::ios_base::failbit
in the stream. When this flag is set, the stream converts to false
, i.e., you can use the stream to see if the input was successful:
if (in >> x >> y >> z) {
if (in >> w) {
deal_with_all_for_values(x, y, z, w);
}
else {
deal_with_only_the_first_tree(x, y, z);
}
}
Most of the values are set only when the read operation is successful, i.e., if you have a special value you want to give to w
you can just read the value and if it isn't present it will retain its original value:
int w = 17;
if (in >> x >> y >> z) {
in >> w;
deal_with_the_values(x, y, z, w);
Upvotes: 2
Reputation: 476950
Do it in two steps:
if (in >> x >> y >> z)
{
mandatory_stuff(x, y, z);
if (in >> w)
{
optional_stuff(w);
}
}
else
{
// malformed input
}
Upvotes: 3