我有一个std :: string 我想在Newa和Newb这样的两个空格之后保留字符串
std::string a = "Command send SET Command comes here";
std::string b = "Command GET Command comes here";
std::string Newa = "SET Command comes here";
std::string Newb = "Command comes here";
我想到的是,我可以做两次std::string::find(' ')
并使用std::string::substr
来获得理想的结果。
我们能以更精致的方式做到吗?
答案 0 :(得分:5)
以下是更通用的方法。 find_n
返回与需要搜索的第n
个元素匹配的元素之后的迭代器。它可以用于在两个空格,三个空格等之间进行拆分。实际上,您可以将其用作其他算法的构造块。如果字符串包含的空格少于两个,则split函数将返回输入字符串。
#include <iostream>
template<class InputIt, class T>
InputIt find_n(InputIt first, InputIt last, const T& value, size_t n)
{
size_t count{0};
while (first != last && count < n) {
if (*first++ == value) ++count;
}
return first;
}
std::string split_after_two_spaces(const std::string& s)
{
const auto it{find_n(s.begin(), s.end(), ' ', 2)};
if (it != s.end()) {
return std::string(it, s.end());
}
return s;
}
int main()
{
const std::string a = "Command send SET Command comes here";
const std::string b = "Command GET Command comes here";
const std::string c = "Command GET";
std::cout << split_after_two_spaces(a) << '\n';
std::cout << split_after_two_spaces(b) << '\n';
std::cout << split_after_two_spaces(c) << '\n';
return 0;
}
我想验证与简单的双find()
和substr()
相比,此方法在性能方面有多糟,事实证明,对于较小的字符串,它要快一些,并且对于较长的输入字符串,速度较慢。 std::string::find()
的速度将比std::find
快,因为它可能已经过优化以专门处理字符串。
更新:find_n
的以下实现效率更高,但不幸的是,它也更加复杂。从某种意义上说,它具有更好的语义,即它将迭代器返回第n
个匹配元素,而不是经过第n
个匹配元素的迭代器。
template<class InputIt, class T>
InputIt find_n(InputIt first, InputIt last, const T& value, size_t n)
{
if (first != last && n > 0)
{
size_t count{0};
do
{
first = std::find(first, last, value);
}
while (first != last && ++count < n);
}
return first;
}
答案 1 :(得分:3)
您可以在sstream
和getline
的帮助下进行尝试:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string a = "Command send SET Command comes here";
stringstream ss(a);
string w1, w2, w3, Newa;
ss >> w1 >> w2 >> w3;
getline(ss, Newa); //get rest of the string!
cout << w3 + Newa << endl;
return 0;
}
"SET Command comes here"
答案 2 :(得分:3)
不需要构造sstream
,只需使用find()
函数两次即可。
下面的函数可以从字符串中删除n
个开头的单词(基于空格,但也可以对其进行参数设置)。您所需要做的就是使用find
查找第一个空格,用子字符串替换输入字符串(从该空格之后的下一个字符开始),然后根据要删除的单词数重复此过程。
#include <iostream>
#include <string>
std::string removeWords(std::string s, int n) {
for(int i=0; i<n; ++i) {
const auto spaceIdx = s.find(' ');
s = s.substr(spaceIdx+1, s.length());
}
return s;
}
int main() {
std::cout << removeWords("Command send SET Command comes here", 2) << '\n';
std::cout << removeWords("Command GET Command comes here", 2) << '\n';
return 0;
}
答案 3 :(得分:1)
嗯,也许我有点误会。我看到许多行的描述,许多行代码,投票和一个可以接受的答案。
但是通常这样的文本替换总是可以单行完成。有专门的功能可用于以下任务:std::regex_replace
。
对性能没有要求,所以我建议使用专用功能。请查看以下单行代码:
#include <iostream>
#include <iterator>
#include <string>
#include <regex>
int main()
{
std::string a{"Command send SET Command comes here"};
std::regex_replace(std::ostreambuf_iterator<char>(std::cout), a.begin(), a.end(), std::regex(R"(.*? .*? (.*$))"), "$1");
return 0;
}
我想是因为如果它很简单,就不需要进一步的解释了。