The other day I created a post over at CodeReview. One person who answered my question suggested that I refrain from using strcasecmp() because the "function is non-standard [and] this makes [my] code non-portable." This is how I used it:
int playGame()
{
char scanned[3];
printf("Do you wish to play tick-tack-toe?\n");
scanf("%s", scanned);
if(strcasecmp(scanned,"yes")==0)
startGame();
else
{
if (strcasecmp(scanned,"no")==0 || strcasecmp(scanned,"nah")==0 || strcasecmp(scanned,"naw")==0)
{
printf("That's too bad!/nThis program will now end.");
return 1;
}
printf("Not valid input!/nThis program will now end.");
return 1;
}
return 0;
}
Can someone explain more in-depth and why strcasecmp() has these limitations?
Then you could use the standard strcmp(). Note that this can be functionally different than strcasecmp() when upper/lower case letters do not have 1-to-1 mappings. It depends on strcasecmp() specifications (it is not C standard) . Most strcasecmp() do use this tolower() approach for the default locale.
The strcasecmp subroutine performs a character-by-character comparison similar to the strcmp subroutine. However, the strcasecmp subroutine is not case-sensitive. Uppercase and lowercase letters are mapped to the same character set value.
The strcasecmp() function compares string1 and string2 without sensitivity to case. All alphabetic characters in string1 and string2 are converted to lowercase before comparison. The strcasecmp() function operates on null terminated strings.
In programming language C, strcasecmp is a function declared in the strings. h header file (or sometimes in string. h) that compares two strings irrespective of the case of characters. This function is in POSIX.
Short answer: As strcasecmp()
is not in the C standard library, that make it non-standard.
strcasecmp()
is defined in a the popular standards such as 4.4BSD, POSIX.1-2001.
The definition of case-less functions opens the door to the nit-picky details. These often involve the positive or negative result of case-less compares, not just the 0 or non-0 as used by OP. In particular:
In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.
The trouble with this is with upper and lower case letters that do not have a 1 to 1 mapping. Consider a local that has E
, e
and é
but no É
, yet toupper('é')
-- > 'E'
. Then with "as if the strings had been converted to lowercase", 'E'
has 2 choices.
As a candidate portable solution consider one that round trips the letter (to upper then to lower) to cope with non 1-to-1 mappings:
int SGA_stricmp(const char *a, const char *b) {
int ca, cb;
do {
ca = * (unsigned char *)a;
cb = * (unsigned char *)b;
ca = tolower(toupper(ca));
cb = tolower(toupper(cb));
a++;
b++;
} while (ca == cb && ca != '\0');
return ca - cb;
}
If you do not want to round-trip the values use:
ca = tolower(ca);
cb = tolower(cb);
Detail: toupper()
and tolower()
only defined for int
in the range of unsigned char
and EOF
. * (unsigned char *)a
used as *a
may have negative values.
strcasecmp is not in the C or C++ standard. It's defined by POSIX.1-2001 and 4.4BSD.
If your system POSIX or BSD compliant, you'll have no problems. Otherwise, the function will be unavailable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With