8

I've been using sscanf and I think I've gotten too comfortable with it. Apparently it is deprecated too and I should use sscanf_s, which is not standard as far as I know. So I was wondering if the STL has an idiomatic C++ replacement do the same thing?

Thanks

I do:

        sscanf(it->second->c_str(),"%d %f %f %f %f %f %f %d \" %[^\"] \" \" %[^\"]",
            &level, &x, &y, &angle, &length, &minAngle, &maxAngle, &relative, name,parentName);
jmasterx
  • 52,639
  • 96
  • 311
  • 557
  • 3
    `sscanf` isn't really deprecated. It is, however, not recommended in C++.`sscanf_s` is a VC++ extension. – Etienne de Martel May 24 '11 at 01:28
  • 5
    You are using VC10? Define _CRT_SECURE_NO_WARNINGS in your property pages and be done with it. – Benjamin Lindley May 24 '11 at 01:31
  • 5
    Bah! The `*_s` functions are for those who should be programming in BASIC. Learn how to use your tools. Otherwise, don't use them at all. In any case, the C++ equivalent to `sscanf` is `sscanf` :-) – paxdiablo May 24 '11 at 01:34

5 Answers5

11

The formatting isn't as easy but check out stringstream. See also istringstream and ostringstream for input and output buffers formatting.

dee-see
  • 23,668
  • 5
  • 58
  • 91
  • 4
    If that is the only solution I'll stick to sscanf, stringstream makes way more lines of code. – jmasterx May 24 '11 at 01:26
  • 1
    Check out this previous question [C++: what benefits do string streams offer?](http://stackoverflow.com/questions/2334735/c-what-benefits-do-string-streams-offer). Maybe you'll find something interesting for you. – dee-see May 24 '11 at 01:32
11

In C++, the ultimate parser is Boost.Qi

#include <boost/spirit/include/qi.hpp>
#include <string>

namespace qi = boost::spirit::qi;

int main()
{
    int level, relative;
    float x, y, angle, length, minAngle, maxAngle;
    std::string name, parentName;

    std::string input = "20 1.3 3.7 1.234 100.0 0.0 3.14 2 \"Foo\" \"Bar\"";
    std::string::iterator begin = input.begin();
    std::string::iterator end = input.end();

    using qi::int_;
    using qi::float_;
    using qi::char_;
    using qi::lit;
    using qi::ascii::space;

    qi::phrase_parse(begin, end,
        int_ >> float_ >> float_ >> float_ >> float_ >> float_ >> float_ >> int_
             >> lit("\"") >> *(~char_('"')) >> lit("\"")
             >> lit("\"") >> *(~char_('"')) >> lit("\""),
        space,
        level, x, y, angle, length, minAngle, maxAngle, relative, name, parentName);
}
xDD
  • 3,443
  • 1
  • 15
  • 12
1

You can try using stringstream. It is much more powerful than sscanf and serves the purpose.

N.R.S.Sowrabh
  • 725
  • 13
  • 30
1

I believe stringstreams are what you are looking for.

for example:

stringstream tokenizer;
string str("42");
int number;

tokenizer << string;
tokenizer >> number;
ladookie
  • 1,343
  • 4
  • 21
  • 24
1

If you're using a compiler with enough C++0x support, it's easy to write a type-safe scanf()-style function... have a read of the printf() example at http://en.wikipedia.org/wiki/C%2B%2B0x to get you started....

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252