-2

I want to remove the space in a string, but when I ran my program and entered "hello world",it did not talk to me. It crashed, which showed:

enter image description here

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string str;
    getline(cin,str);
    int space;
    while(str.find(' ')>=0) {//something wrong happened in the loop
        space = str.find(' ');
        str.erase(space,1);
    }
    cout<<str<<endl;
    return 0;
}

I'm confused exceedingly, because I don't know why my string is out of range.So how to fix it? Thanks in advance.

fgksgf
  • 29
  • 7

1 Answers1

4

Edit:

So the real question was why does it throws an error. std::out_of_range exception is thrown when an index that is not in the range of the container is accessed.

As mentioned in the comments the problem lies in while(str.find(' ')>=0). string::find returns string::npos when it finds nothing. string::npos is defined as -1, but since it's a size_t type, it can't be less that 0. So instead the value is the largest possible unsigned int because it "loops" on its type.

So it will be 4294967295, or whatever value is the maximum for a size_t type on your system and with your compilation flags.

Back to the problem while(str.find(' ')>=0), as said the return of str.find will always be a positive value, so you never stop looping and finally get an std::out_of_rangeexception because you try to access str[string::npos] which is not possible.

The "better' while would then be: while(str.find(' ') != string::npos)

Initial answer:

There is another way to do this using std::remove algorithm. It provides a range to std::erase.

#include <iostream>    
#include <string>
#include <algorithm>

int main()
{
    std::string str = "this is a line";

    std::cout << "before: " << str << std::endl;

    str.erase(std::remove(str.begin(), str.end(), ' '), str.end());

    std::cout << "after: " << str << std::endl;
}
vianney
  • 161
  • 6
  • Thank you, but I still want to know why my program crashed rather than how to remove the space. – fgksgf May 30 '16 at 02:58
  • str.find always return a value >= 0. When it does not find a character it returns `string::npos`, so your code should be `while (str.find(' ') != string::npos)` – vianney May 30 '16 at 03:05
  • Well, it's very kind of you :) . But string::npos is defined with a value of -1. And that's why i'm so confused. – fgksgf May 30 '16 at 03:11
  • Well, yes and no, it's specified that's it's defined as -1 with a size_t type, so it's actually the largest possible value of an unsigned int. – vianney May 30 '16 at 03:14
  • Er, it's difficult for me to understand your words, but I'll try my best. – fgksgf May 30 '16 at 03:23
  • A value of -1 is outside the range of valid indexes for your string, hence the out of range error. – RJM May 30 '16 at 03:24
  • 2
    Basically `size_t` is a typedef of `unsigned int`, as its name hints an unsigned int can't be less than 0. So when you do `unsigned int value = -1` it "loops" and assign `4294967295` instead. Note that this value depends on your system, it's just for the sake of this example. – vianney May 30 '16 at 03:30
  • I'd pad out that comment with a wee bit more explanation and add it to the answer because that is the answer – user4581301 May 30 '16 at 04:02