【问题标题】:Parsing a string in C++ for assigning parameters [duplicate]在C ++中解析字符串以分配参数[重复]
【发布时间】:2011-11-18 02:08:27
【问题描述】:

可能重复:
How do I tokenize a string in C++?

我有一个如下形式的字符串,这是一个用户输入。

a1 10.2 lib_t 50 sv 60 out 'true'

这里a1double类型的参数,其值为10.2。同样,lib_t = 50sv = 60out = 'true' 是一个字符串。

这个输入可以按任意顺序指定..比如lib_t 50 a1 10.2

单词之间的空格可能会有所不同。

编辑: Boost tokenizer 可以处理这个问题。我已经编写了必要的代码。但我想看看是否有任何其他标准方法可以在不使用 boost 库的情况下处理这个问题。

输入很短。我对这里的效率不是很感兴趣(很抱歉在我的原始编辑中使用了“高效”这个词)。

【问题讨论】:

  • any other efficient way?您在寻找什么效率?先写代码,然后再考虑效率!
  • 这里没有实际问题,或者至少我没有看到它。

标签: c++ string parsing boost


【解决方案1】:

如果你有足够符合 C++11 的编译器,你可以在 AX 中编写你的语法(未测试):

std::string input = "a1 10.2 lib_t 50 sv 60 out 'true'";
double d;
unsigned u;
std::string str;

auto space = axe::r_any(" \t");
auto a1_rule = *space & "a1" & +space & axe::r_double(d);
auto lib_t_rule = *space & "lib_t" & +space & axe::r_unsigned(u);
auto string_rule = axe::r_any() - ''';
auto out_rule = *space & "out" & +space & ''' & string_rule >> str & ''';

auto input_rule = +(a1_rule | lib_t_rule | out_rule) & *space & axe::r_end();
input_rule(input.begin(), input.end());

请注意,我在最后一条规则中作弊,实际上它更宽容。如果输入字符串可能不正确并且需要验证,那么您可以使用连接和析取运算符编写更长的规则,枚举所有合法的可能性。此外,您需要确定spacestring_rule 的实际定义是什么。通常将空间定义为 ' ' 或 '\t'。此示例中的string_rule 允许任何字符,除了'''。您可能希望使其更具限制性。还值得一提的是,此解析器将与任何其他输入容器一起使用,而不仅仅是字符串。它还将解析宽字符输入,唯一需要的更改是将str对应地定义为std::wstring str;

【讨论】:

  • 我对 AXE 不熟悉,但您似乎忘记将 r_unsigned(u)axe:: 限定为条件
  • @Mooing Duck -- 你是对的,解决了这个问题。
【解决方案2】:
#include <sstream>
#include <ostream>
#include <istream>
#include <string>
#include <stdexcept>

int main() {
    std::string parameters = "a1 10.2 lib_t 50 sv 60 out 'true'";

    std::stringstream ss(parameters);
    std::string param;
    double a1;
    int libt; //names ending in _t are not allowed
    short sv;
    std::string out;
    while( ss >> param) {
        if (param == "a1")
            ss >> a1;
        else if (param == "lib_t")
            ss >> libt;
        else if (param == "sv")
            ss >> sv;
        else if (param == "out")
            ss >> out;
        else {
            std::stringstream err;
            err << "unknown parameter type: \"" << param << "\"";
            throw std::runtime_error(err.str());
        }
        if (!ss) {
            std::stringstream err;
            err << "error parsing parameter: \"" << param << "\"";
            throw std::runtime_error(err.str());
        }
    }
}

http://ideone.com/zz1r8

可以制作更优化的代码,但会复杂很多,而这相当快速且简单。并且内置了所有错误检查。

【讨论】:

  • 我制作了一个稍微复杂一点的版本 (ideone.com/SUg9G),它速度稍快(尤其是参数更多),并且可以更好地处理更复杂的参数。
猜你喜欢
  • 2017-02-07
  • 2016-07-30
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 2011-05-25
  • 2019-04-02
  • 2013-03-30
  • 1970-01-01
相关资源
最近更新 更多