【问题标题】:std::locale to split string by specific char without ignoring itstd::locale 按特定字符拆分字符串而不忽略它
【发布时间】:2014-09-13 09:09:29
【问题描述】:

我想通过特定字符分割字符串而不忽略它们。

例如,如果我有字符串:

“some_tag = some_value”

我可以使用此语言环境(从 cppreference 复制/改编)将其拆分为标记:

struct split_by_equal : std::ctype<char>
{
    static const mask* make_table()
    {
        static std::vector<mask> v(classic_table(), classic_table() + table_size);
        v['='] |=  space;
        return &v[0];
    }

    split_by_equal() : ctype(make_table()){}
};

...

std::stringstream stream("some_tag = some_value");
stream.imbue(std::locale(std::locale::classic(), new split_by_equal));

std::string token;
while(stream>>token)
{
    std::cout<<token<<std::endl;
}

这可行,但我不知道“=”是否存在一次、多次或丢失。了解这些信息对于验证输入字符串非常重要。

是否可以在不从流中提取字符的情况下使解析停止?

PS:我想使用std::locale,因为真正的问题并不像只使用'='作为分隔符来拆分字符串那么简单:)

编辑:

我希望能够以相同的方式解析以下字符串:

"some_tag=some_value"
"some_tag
=
some_value"
"some_tag = some_value"

并且能够报告下一个错误:

"some_tag some_value"
"some_tag == some_value"

【问题讨论】:

    标签: c++ string c++11 stream


    【解决方案1】:

    更新:我的上一个示例没有考虑您要处理的其他情况。我已经测试了所有这些,它们似乎适用于这个例子:

    template<char c>
    std::istream& strip_until(std::istream& is)
    {
        auto& ctype = std::use_facet<std::ctype<char>>(is.getloc());
        int val = std::char_traits<char>::to_int_type(c);
        bool b;
    
        while ((b = ctype.is(ctype.space, is.peek())) && is.peek() != val)
            is.ignore();
    
        if (!b && is.peek() != val)
            is.setstate(std::ios_base::failbit);
    
        return is;
    }
    
    ...
    
    while (stream >> token >> strip_until<'='>)
    {
        // stream.peek() is '='
    }
    

    【讨论】:

    • 我对“some_tag=some_value”有疑问。这将被读取为一个不带刻面的字符串。
    【解决方案2】:

    您应该将std::getline 与自定义分隔符参数一起使用,然后使用默认'\n' 调用(或更多)。除非您与我们分享完整的问题,否则这仍然是最简单、最有效的解决方案。

    然后您可以检查您希望处理的任何情况。但是处理这样的事情会很困难:

    some_tag
    =
    some_tag = some_value
    

    这似乎是您可能想要处理的情况,尽管这在很大程度上取决于您要解析的内容。

    【讨论】:

      猜你喜欢
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 2014-07-22
      • 2015-12-27
      • 2022-11-22
      相关资源
      最近更新 更多