1

I am getting this error when running:

terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr:

I am brand new, any other tips would be appreciated as well.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string name;
    int position = 1;
    string letter;

    cout << "Enter in your full name seperated by a space: ";
    getline (cin, name);

    cout << name.substr(0, 1);

    while (position <= name.length())
    {
        position++;
        letter = name.substr(position, 1);

        if (letter == " ")
        {
            cout << name.substr(position + 1, 1) << " ";
        }
    }

    cout << endl;

    return 0;
}
Noam M
  • 3,156
  • 5
  • 26
  • 41
Benny Bubu
  • 19
  • 1
  • 1
  • 2
  • 1
    Walk through the values `position` can have with a small string on a piece of paper. – user4581301 Mar 20 '18 at 02:09
  • `position + 1` becomes out-of-bounds on the last three iterations. You got a lot to learn, including how to properly iterate over stuff with 0-indexing. Also, if you just want one letter, use `name[position]`. Recommend getting a [good book](https://stackoverflow.com/q/388242/9254539). – eesiraed Mar 20 '18 at 02:11
  • To iterate over the values in a `string` use a **range-based `for` loop**, like `for( char const ch: name )`. Note that these values are encoding values, which for usual UTF-8 encoding only correspond to characters when those characters are in the ASCII subset. Unfortunately there's no direct support in the C++ library for iterating over *characters*, or for advancing one character, but with UTF-8 this is easy to implement, and for that your approach of representing a character with a string is sensible, and then you'd use an ordinary `for` loop, as you do. – Cheers and hth. - Alf Mar 20 '18 at 02:17

2 Answers2

2

You are trying to reach an index after the last index, you need to change your loop condition to : position < name.length()

and you can solve this problem using for-loop which is more used for such problems, you just need to substitute your while-loop with :

for (int position = 0; position < (name.length()-1); position++) {
    if (name[position] == ' ') {
        cout << name[position+1];
    }
}

Using this you wouldn't need to use substr() method neither string letter .

Ali Safaya
  • 56
  • 9
0

In your loop, position will increase to a number equal to the characters entered by the user (i.e. "Abc Def" last loop iteration: position = 8). In this case name.substr(position, 1); tries to extract the character after the last character in your string, hence the std::out_of_range exception. You may want to change your loop condition to: while (position <= name.length() - 1) or while (position < name.length())

Constantin
  • 8,721
  • 13
  • 75
  • 126
  • That will still be out-of-bounds since he did `name.substr(position + 1, 1)`. – eesiraed Mar 20 '18 at 02:12
  • @FeiXiang It would only be out of bounds, if the input ends with space. – Constantin Mar 20 '18 at 02:13
  • 1
    No, @FeiXiang is right. Also `position++;` takes place after the test. – user4581301 Mar 20 '18 at 02:15
  • @user4581301 No, if the `position` parameter passed to `substr` is equal to the string length, the function returns an empty string. See [here](http://www.cplusplus.com/reference/string/string/substr/). There will be no `std::out_of_range` exception. – Constantin Mar 20 '18 at 02:22
  • I see you. Bad idea, but not fatal. The positioning of the ++ is still a problem though. – user4581301 Mar 20 '18 at 02:24