1

I just have some kind of fundamental perception problem with strcmp, stricmp, compare, etc. I KNOW what they do and I know WHY they do it, but when I'm checking equality I just naturally write "if ( strcmp() )..." It's backwards logic to me and it just doesn't occur to me (until later when my code block doesn't work) to write "if ( 0==strcmp() )...". I do this all the time and it slows down my development. Anyone got a tip to reverse my brain on this?

It's like I needed the function to be named "strdoesntcmp"... (yes I know that it couldn't be used for less- or greater-than that way...). Sure I could use #define or inline to make such a thing but that's a hack... I just want to reverse my natural thinking on it if that makes sense...

mark
  • 5,269
  • 2
  • 21
  • 34
  • 5
    So you want someone to hack into your mind and change the way you think ? Bwong! – cnicutar Sep 10 '12 at 18:59
  • lol i was just about to post that hahaha – im so confused Sep 10 '12 at 19:00
  • Don't write `(0 == whatever)`. It's unintuitive; write the other way around and perhaps you'll remember it better. ("If difference is zero"). – eq- Sep 10 '12 at 19:00
  • 2
    Well you've got it tagged C++, so I would say use the C++ string facilities...but seriously, pick a language. They're not the same. – GManNickG Sep 10 '12 at 19:02
  • @cnicutar: yes! or least a new way of looking at it – mark Sep 10 '12 at 19:04
  • @GmanNickG std::string::compare is the same – mark Sep 10 '12 at 19:05
  • 3
    @mark but you would usually use the `==` operator with std::string – Ben Cottrell Sep 10 '12 at 19:06
  • I would suggest this is a duplicate of http://stackoverflow.com/questions/595450/why-does-strcmp-return-0-when-its-inputs-are-equal – Alexandru C. Sep 10 '12 at 19:09
  • @eq-, this is a suggested way to write equality comparisons. The reasoning is that (0 = x) will not compile, (x = 0) may compile and be a bug. – Josh Petitt Sep 10 '12 at 19:45
  • @eq-, I don't see how "If difference is zero" and "If zero is difference" is different. Probably a personal preference since they are equivalent, and my personal preference is to write the constant on the left. I don't necessarily think there is anything misguided about it, especially since there is one class of bugs that this practice can help avoid? – Josh Petitt Sep 10 '12 at 19:52
  • regarding if (0=x) versus (x=0) i tend to agree with eq- although compilers are pretty good these days about throwing up warnings if you don't do ((x=0))... but for me in this string compare case, putting the ==0 at the end makes my perception problem even that much worse because now i've got to eye-scan to the end of the code line to know the logic direction – mark Sep 10 '12 at 19:53
  • Just keep in mind that `strcmp` means *comparison*, not *equality*. – Keith Thompson Sep 10 '12 at 20:52

4 Answers4

4

The best answer is to forget strcmp entirely.

std::string s1 = "one";
std::string s2 = "two";
if (s1 == s2) // ...

Edit: If you were familiar with assembly the strcmp function wouldn't confuse you at all. Many processors have a CMP instruction that do a subtraction of two values without storing the result, it just sets the condition flags that tell you if the result was negative, zero, or positive. strcmp just simulates the same thing with strings.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • i did start using that convention for std::strings at one point, but it doesn't work in const char * situations of course, and also there's the lack of stricmp and strncmp ability which hindered my "acceptance" of it as my main convention... – mark Sep 10 '12 at 19:08
  • 1
    @mark: " but it doesn't work in const char * situations of course" Says who? `if (s1 == "three")`? Sounds like you need to discover [Boost](http://www.boost.org/). It'll get lots of boiler-plate out of the way. – GManNickG Sep 10 '12 at 19:09
  • @mark - you can override the char_traits in basic_string, which std::string is an instantiation of, and get case insensitivity. Alternatively you can call the old C functions on the return of c_str(). – Edward Strange Sep 10 '12 at 19:25
  • i'm not starting a project from scratch, i'm in a large project with mixed use of C/C++ strings... throwing Boost into it, not a chance. and i can't use std:string (without paying the penalty of creating one) when both strings are const char *... at least one would need to be in that example, and that's also assuming we're not comparing case-insensitive or to n-chars. anyway, like i said, i'm looking for a mind-reset of some kind... – mark Sep 10 '12 at 19:26
  • @mark, you can always construct one of the strings on the fly: `if (std::string("one") == "two")`. And I haven't seen any suggestions for boost, I don't know why you bring it up. – Mark Ransom Sep 10 '12 at 19:29
4
int streq( char const* s1, char const* s2)
{
    return 0 == strcmp(s1, s2);
}

inline it if the performance overhead bothers you.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • He wants to learn "the way", not to invent a workaround. :) – Lorlin Sep 10 '12 at 19:16
  • External identifiers beginning with `str` are reserved for future use, so one should perhaps consider using an alternative name for this helper function. – eq- Sep 10 '12 at 19:16
  • @eq- that's interesting about strxxx being reserved... – mark Sep 10 '12 at 19:47
2

Just think, that comparison is, in fact, subbtraction (the microprocessor instructions are also working in such way). So strcmp might be called strsub, and in such way zero means that the strings are equal.

Or implement the strcmp specification on your own. While you work it out, the return values will glue to your mind like 1x1.

You can think also, that once you have posted to stackOverflow that you are always forgetting (0==strcmp) and got a lot of confusing answers to it. Once you have this remembered, your mind could not mistake anymore that the compare operator is not the equality operator.

Lorlin
  • 844
  • 5
  • 15
  • i like the "subtraction" or "difference" analogy... – mark Sep 10 '12 at 19:45
  • first of all, thanks for answering the question i asked, which was "i need another way of looking at it." after sleeping on this, i think this will work for me... every time i use the strxxx functions, i'm going to think "strdiff"... i.e. if the "difference" is zero, they're the same. i may go so far as to create a strdiff inline, but probably won't use it since it'll be unintuitive to others viewing/editing my code. thanks! – mark Sep 11 '12 at 12:06
0

The reason it's not as intuitive as you want it to be is because you want to use this to compare the strings == or !=. That's not the whole point of the strcmp function. The point is it can return str1 > str2, str1 == str2, or str1 < str2 and you can use those different returns for different reasons.

If you REALLY can't keep them straight in your head, and you only use this function to make == or != type compairions you can always reverse it for yourself:

#define strcmp !strcmp

Then it works they way you want it to, but as I mentioned, you're losing functionality by doing this.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • 1
    You're also going to lose your sanity by doing this. :o – GManNickG Sep 10 '12 at 19:13
  • I would rather make my own function that wraps it. Looking down, I guess that's been suggested :p – chris Sep 10 '12 at 19:13
  • buyer beware. :) I never said it was a **good** idea, just that it will make it "work" as the OP wanted. – Mike Sep 10 '12 at 19:14
  • No; it would perhaps fix a single erroneus condition, but could easily break existing code even in OP's case (as he hinted he's possibly using `strcasecmp` also; he could very well use function pointers to them, too) – eq- Sep 10 '12 at 19:20
  • indeed, disaster would unfold... – mark Sep 10 '12 at 19:46