16

With scanf there's, usually, a direct way to take formatted input:

1) line with a real number higher than 0, and less than 1. Ending on 'x', e.g: 0.32432523x

scanf("0.%[0-9]x", &number);

2) line represents an addition in the format :30+28=fifty-eight

scanf(":%d+%d=%99s", &number1, &number2, &total);

What is the cin solution, using only the standard library?

Alessandro Stamatto
  • 1,489
  • 2
  • 14
  • 18
  • 2
    Nowhere *near* as pretty... `scanf` is really powerful. Personally, I read into a `string`, grab the pointer via `string::c_str()` and then `sscanf` it. Or I tokenise it myself from a `stringstream` or whatever. – paddy Jan 15 '13 at 03:33
  • 1
    For formatted input like this in C++, you might want to consider something like [Boost Spirit](http://boost-spirit.com/home/). It may be overkill, but it'll be cleaner than using iostreams directly. – Jerry Coffin Jan 15 '13 at 03:56
  • 1
    scanf gets the win on this one because it simultaneously gives you a return value that you can check in one place to verify everything matched. In cin stream you'd have to check a few things "manually". – doug65536 Jan 15 '13 at 04:29

2 Answers2

8

You can make a simple class to verify input.

struct confirm_input {
    char const *str;

    confirm_input( char const *in ) : str( in ) {}

    friend std::istream &operator >>
        ( std::istream &s, confirm_input const &o ) {

        for ( char const *p = o.str; * p; ++ p ) {
            if ( std::isspace( * p ) ) {
                std::istream::sentry k( s ); // discard whitespace
            } else if ( (c = s.get() ) != * p ) {
                s.setstate( std::ios::failbit ); // stop extracting
            }
        }
        return s;
     }
};

usage:

std::cin >> x >> confirm_input( " = " ) >> y;
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
6

Use the >> operator to read from cin.

  int number1, number2;
  std::string text;
  char plus, equals;
  std::cin >> number1 >> plus >> number2 >> equals >> text;
  if (!std::cin.fail() && plus == '+' && equals == '=' && !text.empty())
    std::cout << "matched";

It's not as good as scanf because you'd have to verify any literals that were in the scanf string yourself. Doing it with streams will almost certainly be a lot more lines of code than scanf.

I would use scanf.

doug65536
  • 6,562
  • 3
  • 43
  • 53