Fault
Fault

Reputation: 420

Checking for valid input C++

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

Answers (2)

Dietmar Kühl
Dietmar Kühl

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

Kerrek SB
Kerrek SB

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

Related Questions