2009-08-31 16 views
14

Estoy confundido por strcmp(), o mejor dicho, como está definido por el estándar. Considere la posibilidad de comparar dos cadenas donde una contiene caracteres fuera del rango ASCII-7 (0-127).strcmp() y caracteres con firma/sin firma

El estándar C define:

int strcmp (const char * s1, const char * s2);

La función strcmp compara la cadena señalada por s1 con la cadena apuntada por s2.

La función strcmp devuelve un número entero mayor que, igual a, o menor que cero, en consecuencia como la cadena apuntado por s1 es mayor que, igual a, o menor que la cadena apuntada por s2.

Los parámetros son char *. No unsigned char *. No existe la noción de que "la comparación se debe hacer como unsigned".

Pero todas las bibliotecas estándar que revisé consideran que el carácter "alto" es solo eso, mayor en valor que los caracteres ASCII-7.

Entiendo que esto es útil y el comportamiento esperado. No quiero decir que las implementaciones existentes son incorrectas o algo así. Solo quiero saber, , qué parte de las especificaciones estándar he omitido?

int strcmp_default(const char * s1, const char * s2) 
{ 
    while ((*s1) && (*s1 == *s2)) 
    { 
     ++s1; 
     ++s2; 
    } 
    return (*s1 - *s2); 
} 

int strcmp_unsigned(const char * s1, const char *s2) 
{ 
    unsigned char * p1 = (unsigned char *)s1; 
    unsigned char * p2 = (unsigned char *)s2; 

    while ((*p1) && (*p1 == *p2)) 
    { 
     ++p1; 
     ++p2; 
    } 
    return (*p1 - *p2); 
} 

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char x1[] = "abc"; 
    char x2[] = "abü"; 
    printf("%d\n", strcmp_default(x1, x2)); 
    printf("%d\n", strcmp_unsigned(x1, x2)); 
    printf("%d\n", strcmp(x1, x2)); 
    return 0; 
} 

salida es:

103 
-153 
-153 
+0

Eche un vistazo a este artículo. http://www.ddj.com/cpp/184402023 – adatapost

+3

... ¿Cuál es relevante para esta pregunta porque ...? – DevSolar

Respuesta

26

7.21.4/1 (C99), el énfasis es mío:

El signo de un valor distinto de cero devuelto por la comparación funciones memcmp, strcmp , y strncmp está determinado por el signo de la diferencia entre los valores del primer par de caracteres (ambos interpretados como char sin signo) que difieren en los objetos que son comparados.

Hay algo similar en C90.

Tenga en cuenta que strcoll() puede estar más adaptado que strcmp() especialmente si tiene caracteres fuera del conjunto de caracteres básicos.

+0

Excelente. Exactamente el tipo de respuesta que he estado buscando. ¡Gracias! – DevSolar