Estou tentando reimplementar a strcasecmp
função em C e notei o que parece ser uma inconsistência no processo de comparação.
De man strcmp
A função strcmp () compara as duas seqüências s1 e s2. O código do idioma não é levado em consideração (para uma comparação com reconhecimento do código do idioma, consulte strcoll (3)). Retorna um número inteiro menor que, igual a ou maior que zero se s1 for encontrado, respectivamente, menor que, para corresponder ou maior que s2.
De man strcasecmp
A função strcasecmp () executa uma comparação de bytes por bytes das seqüências s1 e s2, ignorando o caso dos caracteres. Retorna um número inteiro menor que, igual a ou maior que zero se s1 for encontrado, respectivamente, menor que, para corresponder ou maior que s2.
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
Dada essa informação, não entendo o resultado do seguinte código:
#include <stdio.h>
#include <string.h>
int main()
{
// ASCII values
// 'A' = 65
// '_' = 95
// 'a' = 97
printf("%i\n", strcmp("A", "_"));
printf("%i\n", strcmp("a", "_"));
printf("%i\n", strcasecmp("A", "_"));
printf("%i\n", strcasecmp("a", "_"));
return 0;
}
Ouput:
-1 # "A" is less than "_"
1 # "a" is more than "_"
2 # "A" is more than "_" with strcasecmp ???
2 # "a" is more than "_" with strcasecmp
Parece que, se o caractere atual em s1
for uma letra, ele sempre será convertido em minúsculas, independentemente de o caractere atual s2
ser uma letra ou não.
Alguém pode explicar esse comportamento? A primeira e a terceira linhas não deveriam ser idênticas?
Agradeço antecipadamente!
PS:
Estou usando o gcc 9.2.0
Manjaro.
Além disso, quando compilo com a -fno-builtin
bandeira, recebo:
-30
2
2
2
Eu acho que é porque o programa não usa as funções otimizadas do gcc, mas a questão permanece.
strcasecmp
você está se referindo não é precisa. Mais detalhes nas respostas votadas.
A < _ && a > _ && A == a
causaria muitos problemas.
unsigned char
. C17 / 18 "Tratamento de strings <string.h>" -> "Para todas as funções desta subcláusula, cada caractere deve ser interpretado como se tivesse o tipo unsigned char
". Isso faz diferença quando os char
valores estão fora do intervalo ASCII de 0 a 127.
printf("%i\n", strcasecmp("a", "_"));
presumivelmente, isso deve ter o mesmo resultado queprintf("%i\n", strcasecmp("A", "_"));
Mas isso significa que uma dessas duas chamadas que não diferenciam maiúsculas de minúsculas vai discordar de sua contraparte que diferencia maiúsculas de minúsculas.