I have a std::string I want to keep the string after two spaces like in Newa and 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";
what comes to my mind is that i can do std::string::find(' ') two times and use std::string::substr to get the desired result.
Can we do it in more refined manner.
The following is a more generalized approach. find_n returns an iterator past the element that matches the n-th element that needs to be searched for. It can be used to split after two spaces, three spaces, etc. You can in fact use it as a building block for other algorithms. The split function will return the input string in case the string contains less than two spaces.
#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;
}
I wanted to verify how much worse this approach would be in terms of performance compared to the straightforward double find() and substr() approach, and it turns out to be a bit faster for small strings, and it is slower for longer input strings. std::string::find() is going to be faster than std::find since it is likely to be optimized to deal with strings specifically.
Update: The following implementation of find_n is more efficient, but also a bit more complex unfortunately. It has nicer semantics in the sense that it returns an iterator to the n-th matching element, instead of an iterator one past the n-th matching element.
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;
}
There's no need to construct sstream, you can just use find() function twice.
The function below can remove n first words from your string (based on spaces, but it can also be parametrized). All you need is to find the first space occurence using find, replace input string with a substring (starting from a next character after that space) and repeat the procedure depending on number of words you want to remove.
#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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With