views:

411

answers:

4

Hi all!

Suppose I have an input file in this format:

VAL1 VAL2 VAL3
VAL1 VAL2 VAL3

I'm writing a program that would be interested only in VAL1 and VAL3. In C, if i wanted to 'skip' the second value, I'd do as follows:

char VAL1[LENGTH]; char VAL3[LENGTH];
FILE * input_file;
fscanf(input_file, "%s %*s %s", VAL1, VAL3);

Meaning, I'd use the "%*s" formatter to make fscanf() read this token and skip it. How do I do this with C++'s cin? Is there a similar command? Or do I have to read to a dummy variable?

Thanks in advance.

+1  A: 

I would just read it into a dummy variable. If you do need it eventually, it will be available.

Daniel A. White
Of course this is my 'default' choice, but I'm willing to avoid it since there will be many (circa 10) tokens I don't want. Plus, there is also my own curiosity of trying to do the thing in a 'beautiful' way. I kind of refuse to believe that something already present in C wasn't considered in the design of C++.
Rafael Almeida
A: 

You can do it in a much easier way with getline(). Just use it to grab the entire line, and then parse out the values in between the tokens (use strtok?)

There are a whole bunch of other issues with getline(), but it should work for your problem.

Suvesh Pratapa
A: 

You can use

cin.ignore(256, ' ');

This will ignore everything up to either 256 characters or a white space.

Edit (formatting and...): alternatives you can do:

int a, b;
cin >> a >> b >> b;
Niki Yoshiuchi
Wow, didn't know that. Nice! :)
Suvesh Pratapa
Creative, but a dummy variable would actually be more clear in this case =)
Rafael Almeida
+3  A: 

There's an ignore function available:

std::cin << val1;
std::cin.ignore (9999, ' ');
std::cin << val3;

The first argument defines the number of characters to skip, the second parameter is the delimiter to stop skipping at.

You could wrap that up in a user-defined manipulator, since it's ugly.


Here's the custom manipulator:

template <class charT, class traits>
inline std::basic_istream<charT, traits> &
ignoreToken (std::basic_istream<charT, traits> &strm)
{
    strm.ignore (9999, ' ');
    return strm;
}

And you could use that like this:

cin >> val1 >> ignoreToken >> val3 >> ignoreToken >> val5;

(ps -- I didn't compile this, so there maybe a typo).

eduffy
This is VERY close to what I want. But is there no way to ignore ANY number of characters (or a whitespace), instead of fixing a really big value?
Rafael Almeida
Nope. You gotta supply a big number. Some of the docs I've read recommend using "std::numerical_limits<int>::max()", but (IMO) that's just silly.
eduffy
std::numeric_limits<std::streamsize>::max() PS. Its not silly, its defensive programming.
Martin York