用sscanf解析输入的C ++替代方法 [英] C++ alternative for parsing input with sscanf

查看:230
本文介绍了用sscanf解析输入的C ++替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的程序期望参数的形式为[ 0.562 , 1.4e-2 ](即成对的浮点数),那么在没有正则表达式的情况下,我该如何在C ++中解析此输入?我知道在涉及用户输入时,有很多情况需要考虑,但是让我们假设给定的输入与上述格式非常匹配(除了后面的空白).

Assuming my program expects arguments of the form [ 0.562 , 1.4e-2 ] (i.e. pairs of floats), how should I parse this input in C++ without regular expressions? I know there are many corner cases to consider when it comes to user input, but let's assume the given input closely matches the above format (apart from further whitespace).

在C语言中,我可以执行类似sscanf(string, "[%g , %g]", &f1, &f2);的操作来提取两个浮点值,这非常紧凑.

In C, I could do something like sscanf(string, "[%g , %g]", &f1, &f2); to extract the two floating point values, which is very compact.

到目前为止,在C ++中,这是我想出的:

In C++, this is what I've come up with so far:

std::string s = "[ 0.562 , 1.4e-2 ]"; // example input

float f1 = 0.0f, f2 = 0.0f;

size_t leftBound = s.find('[', 0) + 1;
size_t count = s.find(']', leftBound) - leftBound;

std::istringstream ss(s.substr(leftBound, count));
string garbage;

ss >> f1 >> garbage >> f2;

if(!ss)
  std::cout << "Error while parsing" << std::endl;

如何改进此代码?特别是,我担心garbage字符串,但是我不知道如何在两个值之间跳过,.

How could I improve this code? In particular, I'm concerned with the garbage string, but I don't know how else to skip the , between the two values.

推荐答案

显而易见的方法是创建一个简单的操纵器并使用它.例如,操纵器使用静态提供的char来确定下一个非空白字符是否为该字符,如果是,则将其提取,如下所示:

The obvious approach is to create a simple manipulator and use that. For example, a manipulator using a statically provided char to determine if the next non-whitespace character is that character and, if so, extracts it could look like this:

#include <iostream>
#include <sstream>

template <char C>
std::istream& expect(std::istream& in)
{
    if ((in >> std::ws).peek() == C) {
        in.ignore();
    }
    else {
        in.setstate(std::ios_base::failbit);
    }
    return in;
}

然后可以使用由此构建的操纵器提取字符:

You can then use the thus build manipulator to extract characters:

int main(int ac, char *av[])
{
    std::string s(ac == 1? "[ 0.562 , 1.4e-2 ]": av[1]);
    float f1 = 0.0f, f2 = 0.0f;

    std::istringstream in(s);
    if (in >> expect<'['> >> f1 >> expect<','> >> f2 >> expect<']'>) {
        std::cout << "read f1=" << f1 << " f2=" << f2 << '\n';
    }
    else {
        std::cout << "ERROR: failed to read '" << s << "'\n";
    }
}

这篇关于用sscanf解析输入的C ++替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆