开发者

C++ how to parse integers (and possibly doubles) from character array (or std::string)?

i am working on simple program and have stuck with this for a few days now.

How to parse integers (and possibly doubles) from character array? If it would be easier, char array can be converted to string, i mean, it is not a must have char array.

I was looking for a C++ way of

sscanf(mystring, "di %lf %lf %lf", &d1, &d2, &d3);

Problem is, i will have multiple lines of unknown length (numbers). And i'll have spaces or comm开发者_如何学编程as or something else delimiting numbers.

Are tokens the way? Of which i know nothing.

Well, thanks for any help.


I'm not too sure what you really need. It sounds like you don't know the exact format of your file. (You've certainly not described anything "exact".) To convert integers or doubles from a string, you should to use istringstream. If you want to support a variety of separators, you could easily write a manipulator to do it, something like:

class skipSeparators
{
    std::string mySeparators;
public:
    skipSeparators( std::string const& separators )
        : mySeparators( separators )
    {
    }
    friend std::ostream&
    operator>>(
        std::ostream& source,
        SkipSeparators const& manip )
    {
        source >> std::ws;
        int next = source.peek();
        if ( next != EOF
                && std::find( mySeparators.begin(),
                              mySeparators.end(),
                              static_cast<char>( next ) 
                            ) != mySeparators.end() ) {
            source.get();
        }
        return source;
    }
};

With this, you could write something like:

while ( input >> skipSeparators( ",;" ) >> someDouble ) {
    //  process some double...
}

If knowing where the line ends were important, you can read the file using getline(), and create an istringstream for each line, using the above on it.


Simple C++ parsers usually look something like this…

struct syntax_error : std::runtime_error {
    syntax_error( char const *str ) : std::runtime_error( str ) {}
};

std::istringstream iss( str ); // str is char*; use str.c_str() for std::string

std::string opcode;
long double args[ args_max ];

iss >> opcode; // read up to whitespace

for ( size_t arg_cnt = 0; arg_cnt < arg_counts[ opcode ]; ++ arg_cnt ) {
    if ( iss >> args[ arg_cnt ] ) { // read number, discard preceding whitespace
        throw syntax_error( "too few args" );
    }

    char delim;
    if ( ! ( iss >> delim ) || delim != ',' ) {
        throw syntax_error( "expected ',' delimiter" );
    }
}


Take a look at Boost's lexical_cast, I think it does exactly what you want. Example from link:

int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜