Reputation: 1796
I want to get a substring from the first appearance of char in string to the end of the string. I thought that I can just use constructor, like in this question, but it doesn't really work. When I do like this:
string(input.find(' ')+1, input.end()-1)
I face "no constructor" error
error: no matching constructor for initialization of 'std::__cxx11::string' (aka 'basic_string<char>')
How can I fix this problem and get my code working?
Upvotes: 5
Views: 15762
Reputation: 69864
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.
Upvotes: 1
Reputation: 238311
I assume that input
is a std::string
If you take a look at the documentation of std::string::find
, you'll find that it returns the index of the found character; not an iterator. In order to use the iterator constructor, you must use:
auto str = std::string(input.begin() + input.find(' '), input.end());
Alternatively, you could use substr
member of input
:
auto str = input.substr(input.find(' '));
The +1 and -1 in your example are confusing. If you add 1 to first, then you get the substring starting after the found character, not starting from the character. If you subtract 1 from the end, you copy until one before the last character, not up to the end of the string.
Note that you probably also need to also handle the case where the character is not found. The constructor approach (as I've implemented) would have undefined behaviour. The substr
approach would throw an exception.
Upvotes: 11
Reputation: 1234
The find
member function of std::string
does not return an iterator.
There is also std::string::substr
which you can use as input.substr(input.find(' ') + 1);
Upvotes: 1