30

I am trying to compile the following very very simple piece of source code:

#include <cstring>
// #include <string.h>
// using namespace std;

class Helper {
public:
    int cStringsAreEqual(const char *s1, const char *s2) {
        return stricmp(s1, s2);
    }
};

... but I am getting the following error message:

   g++ error: ‘stricmp’ was not declared in this scope

However when I use strcmp() instead of stricmp() then everything is fine!

What can be wrong here? Shouldn't stricmp() be allowed when strcmp() is allowed?

Sureley, this all could be written in a much better way without using strcmp/stricmp.

But that's not the point here.

I am porting a piece of software - which makes much use of calls to stricmp(). And if somehow possible I would like to avoid all of the efforts needed to change every call to stricmp.

Any help on this would be very much appreciated!

BTW: I am using Ubuntu karmic OS (v9.10) with g++ v4.4.1.

BTW: as you can see I also made some trials with '#include string.h' or with 'namespace std' but nothing helped.

  • Considering that stricmp and strcmp are not the same (the latter is case sensitive), you might want to hesistate before changing them anyhow. – Brian Nov 23 '09 at 17:44
  • 3
    I *know* that they are not the same. That's why I want to use stricmp and not strcmp –  Nov 23 '09 at 17:47
  • Note also that `` and `` aren't exactly the some. It's not the cause of your problem, but you'll need to write `std::strcmp` (or `std::strcoll`) rather than assuming the names are imported into the global namespace. – Toby Speight Jul 04 '17 at 07:27

5 Answers5

43

Try strcasecmp(). Here's the manual page for it. It is conforming to 4.4BSD and POSIX.1-2001.

Gonzalo
  • 20,805
  • 3
  • 75
  • 78
  • That would be an option. strcasecmp() seems to have the same parameters. So it shouldn't be to difficult to create a small perl script that does a global change. Thanks a lot! –  Nov 23 '09 at 17:52
  • No problem. Also take a look at Mark Rushakoff's comment on how the locale settings affect this function. – Gonzalo Nov 23 '09 at 17:54
  • 2
    Beware that strcasecmp depends on your locale. Thus strcasecmp("div","DIV") will NOT return 0 in a turkish locale (lowercase I is ı). That means it matters where your string comes from :-(. There are other examples in other languages. You might break your program for foreign users. – rockdaboot Sep 18 '14 at 14:30
14

stricmp is neither POSIX nor ANSI, so it doesn't really matter if strcmp is allowed, if your compiler or standard library is strictly adhering to POSIX or ANSI standard library functions (as is probably the case with the GCC suite).

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • 3
    It's complicated, because the idea of "case-sensitivity" can depend on your locale or OS. See some of the answers in this question: http://stackoverflow.com/questions/11635/case-insensitive-string-comparison-in-c – Mark Rushakoff Nov 23 '09 at 17:49
  • I am using Eclipse CDT on windows 7 with Cygwin, and stricmp is accepted there. On my Linux machine, with GCC it is not acepted. Does that means that compiler included with Cygwin IS NOT POSIX or ANSI? – Nenad Bulatović Jun 09 '13 at 09:25
13

Add a define for it to overwrite stricmp with strcasecmp on the platforms you are looking for.

#ifdef _IPHONE <- your platform define here
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif

Then you can just use stricmp always.

Ryan Christensen
  • 7,843
  • 1
  • 27
  • 25
  • where do we put this though – Chit Khine Jan 24 '17 at 07:27
  • Just put it in a header or at the top with any other preprocessor directives (ifdefs/defines): http://www.cplusplus.com/doc/tutorial/preprocessor/ #define _IPHONE would switch to the usage above minus the "<- .. " part" – Ryan Christensen Jan 28 '17 at 01:25
0

If you've got Boost, use boost::algorithm::iequals(s1, s2, std::locale::classic()) in <boost/algorithm/string/predicate.hpp> (or leave off locale if you want locale-sensitivity). It works with C strings, std::[w]string, vector<char>, etc.

Matt Chambers
  • 2,229
  • 1
  • 25
  • 43
-2

Pretty easy to make your own if need be...

int my_stricmp (const char *s1, const char *s2)
{
    while (*s1 != 0 && *s2 != 0)
    {
        if (*s1 != *s2 && ::toupper (*s1) != ::toupper(*s2))
        {
            return -1;
        }
        s1++;
        s2++;
    }
    return (*s1 == 0 && *s2 == 0) ? 0 : -1;
}
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Gary
  • 1
  • How does this return a positive value when `s1` sorts later than `s2`? Or is it intended to have a different interface to `std::strcmp()`? – Toby Speight Jul 04 '17 at 07:31
  • Addressed issue @TobySpeight pointed out. Also corrected if logic. – Jesse Chisholm Aug 23 '17 at 15:35
  • 1
    `CAVEAT`: The calls to `::toupper` are locale specific. You may get different results depending on where you run this. Consider using the locale aware overrides instead. – Jesse Chisholm Aug 23 '17 at 15:36
  • @Jesse, your proposed change was quite substantial, and so was rejected by the reviewers. You might want to add some explanation and turn it into a proper answer instead. – Toby Speight Aug 23 '17 at 16:32
  • @Toby: reviewers be damned. If you have posted an incorrect answer, you should either fix it (yourself if need be), or delete it, or at least flag it prominently as incorrect. – Robin Davies Sep 04 '21 at 02:16