Strcasecmp (): custom function?

The other day I created a post in CodeReview. One person who answered my question suggested that I would refrain from using strcasecmp () because "the non-standard function [and] makes [my] code not portable." Here 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 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 in more detail and why strcasecmp () has these limitations?

+6
source share
4 answers

strcasecmp is not part of the C or C ++ standard. It is defined by POSIX.1-2001 and 4.4BSD.

If your POSIX or BSD system is compatible, you will have no problem. Otherwise, the function will be unavailable.

+3
source

“Non-standard function” means that the function declaration and contract are not specified in International Standard C.

“This makes the code non portable” means that no implementation is required for strcasecmp() , and therefore your code is not completely standard and is not guaranteed to be compiled by strictly standard compilers.

strcasecmp() itself is part of the POSIX.1-2001 and 4.4BSD specifications ( link ).

+1
source

Short answer: since strcasecmp() not in the C standard, this makes it non-standard.

strcasecmp() defined in popular standards such as 4.4BSD, POSIX.1-2001.

Defining functions without taking errors into account opens the door to parts that are not needed. They often include the result + or - without random comparisons, and not just the 0 or non-0 used by the OP. In particular:

In the POSIX locale, strcasecmp () and strncasecmp () should behave as if the strings were converted to lowercase and then the bytes were compared. Results are not defined in other locales.

The problem with this is with lowercase and lowercase letters that do not have a mapping from 1 to 1. Consider a local one that has E , E and é , but not É , but toupper('é')'E' . Then, “if the lines were converted to lowercase”, 'E' has 2 options.

As a portable solution, think of round trips as the letter (upper and lower) to deal with the comparisons not one to one:

 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)); } while (ca == cb && ca != '\0'); return ca - cb; } 

If you do not want to round values, use:

  ca = tolower(ca); cb = tolower(cb); 

In detail: toupper() and tolower() defined only for int in the range from unsigned char and EOF .

0
source

An alternative could be canonicalization of lowercase input using tolower (), which is standard. Then you can use standard strcmp ().

-1
source

Source: https://habr.com/ru/post/989977/


All Articles