2016-01-19 10 views
6

ho cercato di implementare strcmp:Attuazione della strcmp

int strCmp(char string1[], char string2[]) 
{ 
    int i=0,flag=0;  
    while(flag==0) 
    { 
     if (string1[i]>string2[i]) 
     { 
      flag=1; 
     } 
     else if (string1[i]<string2[i]) 
     { 
      flag=-1; 
     } 
     else 
     { 
      i++; 
     } 
    } 
    return flag; 
} 

ma mi sono bloccato con il caso che l'utente di ingresso le stesse stringhe, perché la funzione opera con 1 e -1, ma è doesn' t return 0. Qualcuno può aiutarti? E per favore senza indicazioni!

+0

Eventuali duplicati di [realizzazione strcmp ottimizzato] (http: //stackoverflow.com/questions/20004458/optimized-strcmp-implementation) –

risposta

1

È sembrano voler evitare di aritmetica puntatore che è un peccato perché che rende la soluzione più breve, ma il problema è solo di eseguire la scansione oltre la fine del le stringhe. L'aggiunta di un'interruzione esplicita funzionerà. Il vostro programma leggermente modificato:

int strCmp(char string1[], char string2[]) 
{ 
    int i = 0; 
    int flag = 0;  
    while (flag == 0) 
    { 
     if (string1[i] > string2[i]) 
     { 
      flag = 1; 
     } 
     else if (string1[i] < string2[i]) 
     { 
      flag = -1; 
     } 

     if (string1[i] == '\0') 
     { 
      break; 
     } 

     i++; 
    } 
    return flag; 
} 

Una versione più breve:

int strCmp(char string1[], char string2[]) 
{ 
    for (int i = 0; ; i++) 
    { 
     if (string1[i] != string2[i]) 
     { 
      return string1[i] < string2[i] ? -1 : 1; 
     } 

     if (string1[i] == '\0') 
     { 
      return 0; 
     } 
    } 
} 
17

Uhm .. troppo complicato. Andare per questo:

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

Restituisce < 0, 0 o> 0 come previsto

Non si può fare senza i puntatori. In C, l'indicizzazione di un array è utilizzando i puntatori.

Forse vuoi evitare di utilizzare l'operatore *? :-)

0

Il tuo problema è che non rilevi la fine della stringa e quindi non restituisci zero se entrambe le stringhe terminano prima che venga rilevata una differenza.

Si può semplicemente risolvere questo problema controllando per questo la condizione del ciclo:

while(flag==0 && (string1[i] != 0 | string2[i] != 0)) 

Si noti che entrambe le stringhe vengono controllati, perché se uno solo è alla fine le stringhe non sono uguali e il confronto all'interno del ciclo dovrebbe rilevarlo.

Si prega di notare che il confronto dei caratteri potrebbe non produrre il risultato che ci si potrebbe aspettare. Per uno non è definito se char è firmato o non firmato, pertanto è consigliabile eseguire il cast a unsigned char per il confronto.

Forse una soluzione più pulita sarebbe quella di restituire immediatamente quando si rileva la differenza, che invece di flag = -1 si restituisce -1 direttamente. Ma è più una questione di opinione.

+2

Il '&&' è superfluo, si conosce 'stringa1 [i] == stringa2 [i]' in questa fase. – zakinster

+0

se strin1 è zero e la stringa 2 non è zero si continua nel comportamento indefinito –

+0

@PeterMiehle in questo caso 'stringa1 [i] zakinster

4

Prima di tutto la funzione C standard strcmp confronta elementi di stringhe come aventi tipo unsigned char.

In secondo luogo, i parametri devono essere puntatori a stringhe costanti per fornire il confronto anche per stringhe costanti.

La funzione può essere scritta come segue

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

    while (*p1 && *p1 == *p2) ++p1, ++p2; 

    return (*p1 > *p2) - (*p2 > *p1); 
} 
+0

Preferirei personalmente "while (* p1 && * p1 == * p2) {++ p1, ++ p2}", ma per il resto, bella risposta. – Superlokkus

+0

@Superlokkus Il ciclo potrebbe essere writtten come per (const unsigned char * p1 = (const unsigned char *) s1, * p2 = (const unsigned char *) s2; * p1 && * p1 == * p2; ++ p1, ++ p2); Come vedi il ciclo non ha corpo (affermazione). E ha un altro problema: i puntatori p1 e p2 sono necessari al di fuori del ciclo .; –

+0

@Superlokkus Quindi cambiamolo const char unsigned * p1 = (const unsigned char *) s1, * p2 = (const unsigned char *) s2; for (; * p1 && * p1 == * p2; ++ p1, ++ p2); Ma ancora una volta questo ciclo non ha corpo. Questo è confusionario. –

0

Tratto da here.

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

//using arrays , need to move the string using index 
int strcmp_arry(char *src1, char *src2) 
{ 
    int i=0; 
    while((src1[i]!='\0') || (src2[i]!='\0')) 
    { 
     if(src1[i] > src2[i]) 
      return 1; 
     if(src1[i] < src2[i]) 
      return 1; 
     i++; 
    } 

    return 0; 
} 
//using pointers, need to move the position of the pointer 
int strcmp_ptr(char *src1, char *src2) 
{ 
    int i=0; 
    while((*src1!='\0') || (*src2!='\0')) 
    { 
     if(*src1 > *src2) 
      return 1; 
     if(*src1 < *src2) 
      return 1; 
     src1++; 
     src2++; 
    } 
    return 0; 
} 

int main(void) 
{ 
    char amessage[] = "string"; 
    char bmessage[] = "string1"; 
    printf(" value is %d\n",strcmp_arry(amessage,bmessage)); 
    printf(" value is %d\n",strcmp_ptr(amessage,bmessage)); 
} 

Ho apportato alcune modifiche per farlo funzionare come strcmp.

-1
int strCmp(char string1[], char string2[]) 
{ 
    int i=0,flag=0;  
    while(flag==0) 
    { 
     if (string1[i]>string2[i]) 
     { 
      flag=1; 
     } 
     else if (string1[i]<string2[i]) 
     { 
      flag=-1; 
     } 
     else if (string1[i]==string2[i]) 
     { 
      return 0; 
     } 
     else 
     { 
      i++; 
     } 
    } 
    return flag; 
} 
+0

strCmp ("11", "12") == 0 – mrexodia

1

Questa è un'implementazione 10 codici operativi di strcmp (GCC presume)

int strcmp_refactored(const char *s1, const char *s2) 
{ 
    while (1) 
    { 
     int res = ((*s1 == 0) || (*s1 != *s2)); 
     if (__builtin_expect((res),0)) 
     { 
      break; 
     } 
     ++s1; 
     ++s2; 
    } 
    return (*s1 - *s2); 
} 

Si può provare questa implementazione e confrontarlo con gli altri https://godbolt.org/g/ZbMmYM