我想从字符串中第一次出现char到字符串末尾获得一个子字符串。我认为我可以使用构造函数,就像在这个question中,但它并没有真正起作用。当我喜欢这样的时候:
string(input.find(' ')+1, input.end()-1)
我面临“没有构造函数”的错误
error: no matching constructor for initialization of 'std::__cxx11::string' (aka 'basic_string<char>')
如何解决此问题并使我的代码正常工作?
我认为input
是一个std::string
如果你看一下std::string::find
的文档,你会发现它返回找到的字符的索引;不是迭代器。要使用迭代器构造函数,必须使用:
auto str = std::string(input.begin() + input.find(' '), input.end());
或者,您可以使用substr
的input
成员:
auto str = input.substr(input.find(' '));
你的例子中的+1和-1令人困惑。如果首先添加1,那么您将获得从找到的字符后面开始的子字符串,而不是从字符开始。如果从末尾减去1,则复制到最后一个字符之前的一个,而不是字符串的末尾。
请注意,您可能还需要处理未找到字符的情况。构造函数方法(正如我已实现的那样)将具有未定义的行为。 substr
方法会抛出异常。
find
的std::string
成员函数不返回迭代器。
还有std::string::substr
,你可以用作input.substr(input.find(' ') + 1);
为了防御性编程,您可能需要考虑qazxsw poi中没有空间的病态情况。
这里有两个解决方案,一个使用迭代器和标准算法,另一个使用字符串的input
方法。
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**
注意:这些仅是示例。有很多方法可以给这只猫上皮。