简体   繁体   English

C ++如何从字符数组(或std :: string)解析整数(可能加倍)?

[英]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. 如果更简单,可以将char数组转换为字符串,我的意思是,它不是必须具有char数组。

I was looking for a C++ way of 我在寻找一种C ++方式

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 commas or something else delimiting numbers. 而且我将使用空格或逗号或其他分隔数字的东西。

Are tokens the way? 代币是这样吗? Of which i know nothing. 其中我什么都不知道。

Well, thanks for any help. 好,谢谢您的帮助。

Simple C++ parsers usually look something like this… 简单的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" );
    }
}

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 . (您肯定没有描述任何“精确”的东西。)要从字符串转换整数或双精度数,应使用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. 如果知道行的结尾很重要,则可以使用getline()读取文件,并使用上面的istringstream为每行创建一个istringstream

Take a look at Boost's lexical_cast , I think it does exactly what you want. 看一下Boost的lexical_cast ,我认为它确实可以满足您的需求。 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);
        }
    }
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM