string::npos doesn't match find

Hi. I got a split function that's not working, and I'm very confused as for WHY it doesn't

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::vector<std::string> split(std::string str, std::string token){
    std::vector<std::string>result;
    while(str.size()){
        unsigned int index = str.find(token);
        std::cout << "find: " << index << " npos: " << std::string::npos << std::endl;
        if(index!=std::string::npos){
            result.push_back(str.substr(0,index));
            str = str.substr(index+token.size());
            if(str.size()==0)result.push_back(str);
        }else{
            result.push_back(str);
            str = "";
        }
    }
    return result;
}


the console shows this regardeless of the str and the tokens that I used for tests (the only diference is the size, but find and npos always return the same)
1
2
3
4
find: 4294967295 npos: 18446744073709551615
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 4294967296) > this->size() (which is 5)
Aborted (core dumped)


I read in another topic that if find doesn't find the character (it has to happen at some point) it should return the same value as npos
http://www.cplusplus.com/forum/beginner/233668/
So why does my npos return something different than find??

language: c++
OS: ubuntu
Compiler: GNU GCC
Last edited on
unsigned int is not big enough to store the value of std::string::npos. Use std::size_t instead.

 
std::size_t index = str.find(token);
That was the first part of the problem. The second is playing with signedness.

std::npos is typically defined as (-1), so that if you were to change line 4 to use a signed int, it would have functioned.

The advice remains the same, though: use std::size_t to handle indices.
Gotta love this community. This is my first question here, but it's been practically a must visit since I started learning programming.

Come to think about it, the original came with a signed int, and I changed it to unsigned because I got a warning for comparing signed and unsigned. This was a few days ago and had completely forgotten about it (my code hadn't gotten to the point of needing this function yet).

unsigned int returned -1 on find, but it still evaluates as true against npos.
I'll keep std::size_t so i can get rid of the warning.

Thanks a lot!
npos is of an unsigned type, same as returned by the find function.

Changing it to signed int would most probably work, but I don't think it's the correct solution. My understanding is that assigning to a signed type, a value that is bigger than the signed type can handle, is technically an overflow, which is strictly speaking undefined behaviour.
+1
Topic archived. No new replies allowed.