Estoy tratando de reimplementar la strcasecmp
función en C y noté lo que parece ser una inconsistencia en el proceso de comparación.
Desde man strcmp
La función strcmp () compara las dos cadenas s1 y s2. La configuración regional no se tiene en cuenta (para una comparación de configuración regional, consulte strcoll (3)). Devuelve un número entero menor, igual o mayor que cero si se encuentra s1, respectivamente, menor que, para que coincida o mayor que s2.
Desde man strcasecmp
La función strcasecmp () realiza una comparación byte por byte de las cadenas s1 y s2, ignorando el caso de los caracteres. Devuelve un número entero menor, igual o mayor que cero si se encuentra s1, respectivamente, menor que, para que coincida o mayor que s2.
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
Dada esta información, no entiendo el resultado del siguiente 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, si el carácter actual en s1
es una letra, siempre se convierte en minúsculas, independientemente de si el carácter actual en s2
es una letra o no.
¿Alguien puede explicar este comportamiento? ¿No deberían ser idénticas las líneas primera y tercera?
¡Gracias de antemano!
PD:
estoy usando gcc 9.2.0
en Manjaro.
Además, cuando compilo con la -fno-builtin
bandera me sale en su lugar:
-30
2
2
2
Supongo que es porque el programa no usa las funciones optimizadas de gcc, pero la pregunta sigue siendo.
strcasecmp
que te refieres no es precisa. Más detalles en las respuestas votadas.
A < _ && a > _ && A == a
causaría tantos problemas.
unsigned char
. C17 / 18 "Manejo de cadenas <string.h>" -> "Para todas las funciones en esta subcláusula, cada carácter se interpretará como si tuviera el tipo unsigned char
". Esto hace la diferencia una vez que los char
valores están fuera del rango ASCII 0-127.
printf("%i\n", strcasecmp("a", "_"));
presumiblemente, esto debería tener el mismo resultado queprintf("%i\n", strcasecmp("A", "_"));
Pero eso significa que una de estas dos llamadas que no distinguen entre mayúsculas y minúsculas no estará de acuerdo con su contraparte sensible a mayúsculas y minúsculas.