7

With scanf one is allowed to skip matched tokens, simply adding * to the pattern, as in:

int first, second;
scanf("%d %*s %d", &first, &second);

Is there any equivalent approach with std::cin? Something like (of course, sparing the usage of additional variables):

int first, second;
std::cin >> first >> `std::skip` >> second;
Rubens
  • 14,478
  • 11
  • 63
  • 92

3 Answers3

3

You are probably looking for C++ String Toolkit Library.

Check this for more example

Or you may try with ignore function like this:

std::cin >> val1;
std::cin.ignore (1234, ' ');
std::cin >> val3;

Something like this:-

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

And then use like:

cin >> val1 >> ignoreToken >> val3 >> ignoreToken >> val5;
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • Although it seems to be the only available option from stl, I was expecting something a bit neatier. A `std::ios::skip::str` and `std::ios::skip::dec` and even `std::ios::skip::any` would be very nice (: – Rubens Sep 28 '13 at 15:35
  • 1
    +1 I never meant your post didn't help! ^^ Thanks for the functional example! (: – Rubens Sep 28 '13 at 15:45
3

It's not a simple task for input streams in C++ to do same thing. Function scanf gets all expected format: "%d %*s %d" and can look ahead to determine what's going on.

On the other hand, operator >> just tries to satisfy current entry parameter.


You have chances to write you own istream manipulator to eat inputs until reaching a digit.

Try this my naive code:

template<typename C, typename T>
basic_istream<C, T>&
eat_until_digit(basic_istream<C, T>& in)
{
  const ctype<C>& ct = use_facet <ctype<C>> (in.getloc());

  basic_streambuf<C, T>* sb = in.rdbuf();

  int c = sb->sgetc();
  while (c != T::eof() && !ct.is(ctype_base::digit, c))
      c = sb->snextc();

  if (c == T::eof())
      in.setstate(ios_base::eofbit);

  return in;
}

int main()
{
    int first, second;

    cin >> first >> eat_until_digit >> second;

    cout << first << " : " << second << endl;
}

You can extend and improve above code to achieve what you need.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • +1 Sounds reasonable! ^^ And what about a set of skips, like `std::ios::skip::str`, `std::ios::skip::dec`, and even `std::ios::skip::any`? Too messy? (: – Rubens Sep 28 '13 at 15:38
  • Doesn't `std::ctype::scan_is` do this? – David G Oct 25 '13 at 00:04
  • @0x499602D2: `scan_is` is useful to find masks and somehow can be used **inside** the above function since the OP needs an IO manipulator to consume the input like `cin >> eat_until_digit` – masoud Oct 25 '13 at 08:08
2

You can simply use a dummy variable

int first, second;
std::string dummy;
cin >> first >> dummy >> second;

but there's no direct equivalent AFAIK.

john
  • 85,011
  • 4
  • 57
  • 81
  • Yes, that's why I pointed "*of course, sparing the usage of additional vars*". I'm getting used to the idea of this being the only solution, anyway \= – Rubens Sep 28 '13 at 15:31
  • @Rubens, sorry missed that. – john Sep 28 '13 at 15:36