example c string

example - ¿Cómo funciona strcmp()?



strcpy (9)

He estado buscando un poco por una respuesta. Voy a hacer una serie de mis propias funciones de cadena como my_strcmp() , my_strcat() , etc.

¿ strcmp() funciona con cada índice de dos matrices de caracteres y si el valor ASCII es más pequeño en un índice idéntico de dos cadenas, esa cadena es alfabéticamente mayor y, por lo tanto, se devuelve un 0 o 1 o 2? Supongo que lo que pregunto es: ¿utiliza los valores ASCII de los caracteres para devolver estos resultados?

Cualquier ayuda sería muy apreciada.

[REVISADO]

OK, así que he encontrado esto ... funciona para todos los casos, excepto cuando la segunda cadena es mayor que la primera.

¿Algun consejo?

int my_strcmp(char s1[], char s2[]) { int i = 0; while ( s1[i] != ''/0'' ) { if( s2[i] == ''/0'' ) { return 1; } else if( s1[i] < s2[i] ) { return -1; } else if( s1[i] > s2[i] ) { return 1; } i++; } return 0; } int main (int argc, char *argv[]) { int result = my_strcmp(argv[1], argv[2]); printf("Value: %d /n", result); return 0; }


Aquí está la implementación de BSD :

int strcmp(s1, s2) register const char *s1, *s2; { while (*s1 == *s2++) if (*s1++ == 0) return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); }

Una vez que hay una falta de coincidencia entre dos caracteres, simplemente devuelve la diferencia entre esos dos caracteres.


Aquí está mi versión, escrita para pequeñas aplicaciones de microcontroladores, compatible con MISRA-C. El objetivo principal de este código era escribir código legible, en lugar del goo de una línea que se encuentra en la mayoría de las librerías de compilación.

int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while ( (*s1 != ''/0'') && (*s1 == *s2) ) { s1++; s2++; } return (int8_t)( (int16_t)*s1 - (int16_t)*s2 ); }

Nota: el código asume el tipo int 16 bits.


Así es como implementé mi strcmp: funciona así: compara la primera letra de las dos cadenas, si es idéntica, continúa con la siguiente letra. Si no, devuelve el valor correspondiente. Es muy simple y fácil de entender: #incluir

//function declaration: int strcmp(char string1[], char string2[]); int main() { char string1[]=" The San Antonio spurs"; char string2[]=" will be champins again!"; //calling the function- strcmp printf("/n number returned by the strcmp function: %d", strcmp(string1, string2)); getch(); return(0); } /**This function calculates the dictionary value of the string and compares it to another string. it returns a number bigger than 0 if the first string is bigger than the second it returns a number smaller than 0 if the second string is bigger than the first input: string1, string2 output: value- can be 1, 0 or -1 according to the case*/ int strcmp(char string1[], char string2[]) { int i=0; int value=2; //this initialization value could be any number but the numbers that can be returned by the function while(value==2) { if (string1[i]>string2[i]) { value=1; } else if (string1[i]<string2[i]) { value=-1; } else { i++; } } return(value); }



Es solo esto:

int strcmp(char *str1, char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); }

Si desea más rápido, puede agregar "registro" antes del tipo, como este: registrar char

entonces, así:

int strcmp(register char *str1, register char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); }

De esta manera, si es posible, se utiliza el registro de la ALU.


Este código es equivalente, más corto y más legible:

int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while( (*s1!=''/0'') && (*s1==*s2) ){ s1++; s2++; } return (int8_t)*s1 - (int8_t)*s2; }

Solo necesitamos probar el final de s1, porque si llegamos al final de s2 antes del final de s1, el bucle terminará (ya que * s2! = * S1).

La expresión de retorno calcula el valor correcto en cada caso, siempre que solo estemos usando caracteres de 7 bits (ASCII puro). Es necesario pensar detenidamente para producir el código correcto para los caracteres de 8 bits, debido al riesgo de desbordamiento de enteros.


Esto, de los propios maestros ( K&R , 2ª ed., Pág. 106):

// strcmp: return < 0 if s < t, 0 if s == t, > 0 if s > t int strcmp(char *s, char *t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == ''/0'') return 0; return s[i] - t[i]; }


La "implementación" de pseudo-código de strcmp sería algo así como:

define strcmp (s1, s2): p1 = address of first character of str1 p2 = address of first character of str2 while contents of p1 not equal to null: if contents of p2 equal to null: return 1 if contents of p2 greater than contents of p1: return -1 if contents of p1 greater than contents of p2: return 1 advance p1 advance p2 if contents of p2 not equal to null: return -1 return 0

Eso es básicamente eso. Cada carácter se compara a su vez y se toma una decisión sobre si la primera o la segunda cadena es mayor, en función de ese carácter.

Solo si los caracteres son idénticos, se mueve al siguiente carácter y, si todos los caracteres son idénticos, se devuelve cero.

Tenga en cuenta que no necesariamente obtendrá 1 y -1, las especificaciones dicen que cualquier valor positivo o negativo será suficiente, por lo que siempre debe verificar el valor de retorno con < 0 , > 0 o == 0 .

Convertir eso en C real sería relativamente simple:

int myStrCmp (const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (*p1 != ''/0'') { if (*p2 == ''/0'') return 1; if (*p2 > *p1) return -1; if (*p1 > *p2) return 1; p1++; p2++; } if (*p2 != ''/0'') return -1; return 0; }

También tenga en cuenta que "mayor" en el contexto de los caracteres no se basa necesariamente en un ordenamiento ASCII simple para todas las funciones de cadena.

C tiene un concepto llamado ''locales'' que especifica (entre otras cosas) la recopilación o el ordenamiento del conjunto de caracteres subyacente y puede encontrar, por ejemplo, que los caracteres a , á , à y ä se consideran idénticos. Esto sucederá para funciones como strcoll .


Utiliza los valores de bytes de los caracteres, devolviendo un valor negativo si la primera cadena aparece antes de la segunda (ordenada por los valores de bytes), cero si son iguales y un valor positivo si la primera aparece después de la segunda. Dado que opera en bytes, no es compatible con la codificación.

Por ejemplo:

strcmp("abc", "def") < 0 strcmp("abc", "abcd") < 0 // null character is less than ''d'' strcmp("abc", "ABC") > 0 // ''a'' > ''A'' in ASCII strcmp("abc", "abc") == 0

Más precisamente, como se describe en la especificación del grupo abierto strcmp :

El signo de un valor de retorno que no sea cero se determinará por el signo de la diferencia entre los valores del primer par de bytes (ambos interpretados como caracteres sin signo) que difieren en las cadenas que se comparan.

Tenga en cuenta que el valor de retorno puede no ser igual a esta diferencia, pero llevará el mismo signo.