5

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?

2
  • @Yashas any non-empty string with char from input.find and some other symbols, like "Stack overflow" Commented Mar 17, 2019 at 17:57
  • 2
    find does not return an iterator, this is the problem you have Commented Mar 17, 2019 at 17:59

3 Answers 3

11

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.

Sign up to request clarification or add additional context in comments.

4 Comments

You actually don't need the second argument for substr as you need to go up to the end ;)
@Yashas I had assumed that OP wanted substring up to one before the end as per the example code. That appears to conflict with the description though...
Oh, I see. The example code and the description conflict with each other. I think the OP does not want the space to be a part of the substring so you would have to add a +1 to the index before passing to substr.
won't the first solution be UB if the space is not found?
1

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);

2 Comments

But why can't I use constructor as in question i mentioned?
because input.find does not return an iterator
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.