C ++如何从字符数组(或std :: string)解析整数(可能还有双精度数)?

时间:2011-04-13 13:42:26

标签: c++ arrays string parsing

我正在制作一个简单的程序,现在已经坚持了几天。

如何从字符数组中解析整数(可能还有双精度数)? 如果它更容易,char数组可以转换为字符串, 我的意思是,它不是必须有char数组。

我一直在寻找C ++的

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

问题是,我将有多行未知长度(数字)。 我会用空格或逗号或其他分隔数字的东西。

令牌是这样的吗?其中我一无所知。

好的,谢谢你的帮助。

3 个答案:

答案 0 :(得分:0)

简单的C ++解析器通常看起来像这样......

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" );
    }
}

答案 1 :(得分:0)

我不太确定你真正需要什么。听起来你不是 知道你文件的确切格式。 (你当然不是 描述了什么&#34; exact&#34;。)转换整数或双精度数 从字符串中,您应该使用istringstream。如果你想 为了支持各种分隔符,你可以轻松编写 这样做的操纵者,如:

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;
    }
};

有了这个,你可以这样写:

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

如果知道线的结束位置很重要,你可以阅读 文件使用getline(),并为每个文件创建istringstream 线,使用上面的。

答案 2 :(得分:0)

看看Boost's lexical_cast,我认为它完全符合您的要求。链接示例:

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);
        }
    }
    ...
}