2009-08-31 17 views
14

Sono confuso da strcmp(), o meglio, come è definito dallo standard. Considera di confrontare due stringhe in cui una contiene caratteri al di fuori dell'intervallo ASCII-7 (0-127).strcmp() e caratteri firmati/non firmati

Lo standard C definisce:

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

La funzione strcmp confronta la stringa puntata da s1 alla stringa indicata da s2.

La funzione strcmp restituisce un intero maggiore di, uguale o minore di zero, pertanto come la stringa puntata da s1 è maggiore , uguale o minore della stringa puntata da s2.

I parametri sono char *. Non unsigned char *. Non c'è idea che "il confronto dovrebbe essere fatto come unsigned".

Ma tutte le librerie standard che ho controllato considerano il carattere "alto" solo quello, superiore a in valore rispetto ai caratteri ASCII-7.

Capisco che questo è utile e il comportamento previsto. Non voglio dire che le implementazioni esistenti siano sbagliate o qualcosa del genere. Voglio solo sapere, quale parte nelle specifiche standard ho perso?

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; 
} 

uscita è:

103 
-153 
-153 
+0

Date un'occhiata a questo articolo. http://www.ddj.com/cpp/184402023 – adatapost

+3

... che è rilevante per questa domanda perché ...? – DevSolar

risposta

26

7.21.4/1 (C99), corsivo è mio:

Il segno di un valore diverso da zero restituito dal confronto funzioni memcmp, strcmp , e strncmp è determinato dal segno della differenza tra i valori della prima coppia di caratteri (entrambi interpretati come char unsigned) che differiscono per gli oggetti pari a confrontati.

C'è qualcosa di simile in C90.

noti che strcoll() può essere più adatto di strcmp(), soprattutto se si ha il carattere di fuori del set di caratteri di base.

+0

Eccellente. Esattamente il tipo di risposta che stavo cercando. Grazie! – DevSolar

Problemi correlati