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

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

本文关键字:整数 双精度 数组 字符 std string c++      更新时间:2023-10-16

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

如何解析整数(和可能的双精度)从字符数组?如果简单的话,char数组可以转换为字符串,我的意思是,它不是必须的字符数组。

我正在寻找一种c++方式

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

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

令牌在路上吗?我对此一无所知。

好的,谢谢你的帮助。

我不太确定你到底需要什么。听起来你不知道了解文件的确切格式。(你当然没有描述任何"确切"的东西。)转换整数或双精度从一个字符串,你应该使用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

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

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