使用迭代器从std :: string获取子字符串

时间:2019-03-17 17:51:58

标签: c++ string iterator std

我想要从字符串中char的第一个出现到字符串结尾的子字符串。我以为我可以像在question中那样使用构造函数,但实际上并没有用。 当我这样做时:

string(input.find(' ')+1, input.end()-1)

我遇到“没有构造函数”错误

error: no matching constructor for initialization of 'std::__cxx11::string' (aka 'basic_string<char>')

如何解决此问题并使我的代码正常工作?

3 个答案:

答案 0 :(得分:4)

我认为inputstd::string

如果查看std::string::find的文档,您会发现它返回找到的字符的索引;不是迭代器。为了使用迭代器构造函数,必须使用:

auto str = std::string(input.begin() + input.find(' '), input.end());

或者,您可以使用substr的{​​{1}}成员:

input

示例中的+1和-1令人困惑。如果先加1,则子字符串将从找到的字符开始之后,而不是从字符开始。如果从末尾减去1,则会复制到最后一个字符之前的第一个字符,而不是直到字符串末尾。


请注意,您可能还需要处理找不到字符的情况。构造方法(如我所实现的)将具有不确定的行为。 auto str = input.substr(input.find(' ')); 方法将引发异常。

答案 1 :(得分:1)

find的{​​{1}}成员函数不返回迭代器。

还有std::string::substr,您可以用作std::string

答案 2 :(得分:1)

For the sake of defensive programming, you may want to consider the pathalogical case where there is no space in the input.

Here are two solutions, one using iterators and standard algorithms, the other using string's find method.

#include <string>
#include <algorithm>
#include <iostream>

std::string 
all_after_space_iters(std::string const& input)
{
    auto last = input.end();

    auto after_found = [&]
    {
        auto current = std::find(input.begin(), last, ' ');
        if (current != last)
            current = std::next(current);
        return current;
    };

    return std::string(after_found(), last);
}


std::string 
all_after_space_no_iters(std::string const& input)
{
    auto pos = input.find(' ');

    auto result = std::string();
    if (pos != std::string::npos)
    {
        result = input.substr(pos + 1);
    }
    return result;
}

std::string check(std::string s)
{
    if (s.empty())
        s = "**empty**";
    return s;
}


int main()
{
    std::cout << check(all_after_space_iters("dog cat")) << '\n';
    std::cout << check(all_after_space_no_iters("dog cat")) << '\n';
    std::cout << check(all_after_space_iters("dogcat")) << '\n';
    std::cout << check(all_after_space_no_iters("dogcat")) << '\n';
}

Expected Output:

cat
cat
**empty**
**empty**

http://coliru.stacked-crooked.com/a/44e484d3325d195e

Note: these are examples only. There are many ways to skin this cat.