Comparing strings always returning false

Sep 3, 2016 at 10:36pm
I'm trying to compare a substring to a string that I have written, like below, but the if statement is always returning false for some reason.

1
2
3
if(string.substr(4, 5) == "FA" || string.substr(4, 5) == "SP"){
    //do something with string
}


In this case, the string is equal to "2010SP 10" - I have confirmed this in the debugger. The program makes it to the if statement, but then always skips right over it, even though from what I can tell, the second part of the if statement is definitely true. Any help would be greatly appreciated.
Sep 3, 2016 at 10:45pm
The second parameter to std::string::substr() is the length of the returned string.
std::string("0123456789").substr(3, 2) == "34"
std::string("0123456789").substr(7, 5) == "789"

Note that your predicate may construct the same string twice in a row.
1
2
auto s = string.substr(4, 2);
if(s == "FA" || s == "SP")
Sep 3, 2016 at 10:49pm
Oh, thanks. That notation seems so odd to me though. Any reason why the parameters aren't like how I tried them to begin with?
Sep 3, 2016 at 10:59pm
substr() (sometimes called mid()) is a common string operation in many languages and it behaves like this by convention. There's no specific reason for it to behave one way or the other, but it has existed for decades, so now everyone expects it to behave like this.

If you want to construct substrings from absolute offsets, you can still do it:
1
2
3
4
5
6
7
8
9
std::string s = "0123456789";
assert(std::string(s.begin() + 3, s.begin() + 5) == "34");

//Warning: the following assertion is not true! s.size() == 10, so s.begin() + 12 is an
//invalid iterator. Calling the constructor with these arguments will cause undefined behavior.
//This is one of the good things of substr(): it performs bounds-checking.
assert(std::string(s.begin() + 7, s.begin() + 12) == "789");

assert(std::string(s.begin() + 7, s.end()) == "789");
Topic archived. No new replies allowed.