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

Getting a substring from a std::string with iterators

本文关键字:获取 字符串 string std 迭代器      更新时间:2023-10-16

我想从字符串中的首次亮相到字符串的末端获得一个子字符串。我以为我可以像在这个问题一样使用构造函数,但实际上并不奏效。当我喜欢这样的时候:

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

我面对"无构造函数"错误

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

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

我假设inputstd::string

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

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

另外,您可以使用substr的CC_4成员:

auto str = input.substr(input.find(' '));

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


请注意,您可能还需要处理未找到角色的情况。构造函数方法(如我所实施的)将具有未定义的行为。substr方法会引发例外。

std::stringfind成员功能不返回迭代器。

还有std::string::substr,您可以用作input.substr(input.find(' ') + 1);

为了防御性编程,您可能需要考虑 input中没有空间的病理。

这是两个解决方案,一种使用迭代器和标准算法,另一种使用String的find方法。

#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';
}

预期输出:

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

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

注意:这些仅是示例。这只猫有很多方法。