help with std::string::npos

I'm trying to learn C++ and have an exercise to perform a case sensitive/insensitive search on a string and return the position if found. We were given the function prototype - up to me how I implement it. Im trying to get sensitive part to work first. This is what I have so far. Question I have is why does my else statement retun garbage and not npos which is -1?


Thanks in advance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <sstream>
#include <string>

enum class Case{SENSITIVE, INSENSITIVE};

size_t Find(
            const std::string &source,//Source string to be searched
            const std::string &search_string,//The string/char to search for
            Case searchCase = Case::INSENSITIVE,//choose whether search is case senisitive or not
            size_t offset = 0){ //start the search from this offset
    
    if(searchCase == Case::SENSITIVE){
        auto position = source.find(search_string, offset);
        if(position != std::string::npos){
            return position;
        }
        else{
            std::cout << "Not Found" << std::endl;
            return source.npos;
        }
    }
    
    return 0;
    
}

int main(int argc, const char * argv[]) {
   
    
    std::string input {"Hello World"};
    std::string search{"w"};
    
    auto result = Find(input, search, Case::SENSITIVE, 0);
    
    std::cout << result << std::endl;
    
    
    return 0;
}
Last edited on
Although that value seems odd it isn't, you are getting that value because of how string::npos holds the value of -1. And due to the fact that your function returns a type of size_t, an unsigned integer, it's ultimately represented by wrapping around from the maximum size to hold the value. In simple terms, since the number is negative, it will show itself as a positive by using the maximum value size_t can hold + 1 minus the value.

Change the type of size_t to int and you'll see npos being -1. Likewise, try returning negative values differing from -1 to see its effects.

Generally speaking you should check if result is equal to -1 and if so print it otherwise don't or manually print -1.
Last edited on
As an aside, if you stick with programming, you'll start to see certain numbers come up often enough that you recognise they're meaningful in binary and thus some kind of special value that gives you a clue.

Take the number you were getting, and put it into https://codebeautify.org/decimal-binary-converter ; take a look at the binary.
Excellent - thanks for your help. I was on for a quite while wondering why I was getting 18446744073709551615 returned. I have had anothe go below. Still a bit of fine tuning to go but its getting there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

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

enum class Case{SENSITIVE, INSENSITIVE};

size_t Find(
            const std::string &source,//Source string to be searched
            const std::string &search_string,//The string/char to search for
            Case searchCase = Case::INSENSITIVE,//choose whether search is case senisitive or not
            size_t offset = 0){ //start the search from this offset
    
    std::string search_string_toupper = search_string;
    std::transform(search_string_toupper.begin(),search_string_toupper.end(),search_string_toupper.begin(), ::toupper);
    
    auto position = source.find(search_string, offset);
    auto upper_position = source.find(search_string_toupper, offset);
    
    //always carry out case sensitive search first, will return if found
    if(position != std::string::npos){
        return position;
    }//if not found above and requested INSENSITIVE search using transformed string, return if found
    else if(position == std::string::npos && searchCase == Case::INSENSITIVE){
        return upper_position;
    }
    
    //return if neither above is true
    return std::string::npos;
    
}

int main(int argc, const char * argv[]) {
   
    
    std::string input {"Hello World"};
    std::string search{"w"};
    
    auto npos = std::string::npos;
    auto result = Find(input, search, Case::SENSITIVE, 0);
    
    if( result == npos){
        std::cout << "Not Found" << std::endl;
    }
    else{
        std::cout << "Found at position: " << result << std::endl;
    }
    
    //std::cout << npos << std::endl;
    
    return 0;
}

Registered users can post here. Sign in or register to post.