funciona fscanf fprintf como archivos c string input fgets strcmp

fprintf - fscanf



strcmp en una lĂ­nea de lectura con fgets (6)

Estoy tratando de comparar dos cadenas. Uno almacenado en un archivo, el otro recuperado del usuario (stdin).

Aquí hay un programa de muestra:

int main() { char targetName[50]; fgets(targetName,50,stdin); char aName[] = "bob"; printf("%d",strcmp(aName,targetName)); return 0; }

En este programa, strcmp devuelve un valor de -1 cuando la entrada es "bob" . ¿Por qué es esto? Pensé que deberían ser iguales. ¿Cómo puedo obtenerlo para que lo sean?


Porque Fgets está incorporando el carácter de nueva línea en la variable targetName . Esto está arrojando fuera de la comparación.


Principalmente debido al final de la línea de caracteres en la entrada "/ n" bajo un sistema tipo Unix.


fgets agrega la nueva línea a la cadena, por lo que terminarás con bob/n/0 que no es lo mismo que bob/0 .


fgets lee hasta que ve una línea nueva y luego regresa, por lo que cuando escribe bob, en la consola, targetName contiene "bob / n" que no coincide con "bob". De la documentación de los fgets: (negrita agregada)

Lee los caracteres del flujo y los almacena como una cadena C en str hasta que se lean (num-1) caracteres o se llegue a una nueva línea o al final del archivo, lo que ocurra primero. Un carácter de nueva línea hace que los fragmentos dejen de leer, pero se considera un carácter válido y, por lo tanto, se incluye en la cadena copiada en str. Un carácter nulo se agrega automáticamente en str después de que los caracteres se leen para señalar el final de la cadena C.

Debe eliminar la nueva línea del final de targetName antes de comparar.

int cch = strlen(targetName); if (cch > 1 && targetName[cch-1] == ''/n'') targetName[cch-1] = ''/0'';

o agregue la nueva línea a su cadena de prueba.

char targetName[50]; fgets(targetName,50,stdin); char aName[] = "bob/n"; printf("%d",strcmp(aName,targetName));


El fgets se agrega /n a la cadena que está ingresando del usuario cuando presionan Enter. Puede evitar esto usando strcspn o simplemente agregando /n al final de la cadena que está tratando de comparar.

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: /n"); fgets(temp, 8, stdin); temp[strcspn(temp, "/n")] = ''/0''; if(strcmp(temp, "ls") == 0 || strcmp(temp, "exit") == 0)

Esto simplemente reemplaza el /n con un /0 , pero si quieres ser perezoso puedes hacer esto:

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: /n"); fgets(temp, 8, stdin); if(strcmp(temp, "ls/n") == 0 || strcmp(temp, "exit/n") == 0)

Pero no es tan elegante.


strcmp es una de las pocas funciones que tiene los resultados inversos de verdadero y falso ... si las cadenas son iguales, el resultado es 0, no 1, como crees ...

if (strcmp(a, b)) { /* Do something here as the strings are not equal */ } else { /* Strings are equal */ }

Hablando de fgets , hay una probabilidad de que haya una nueva línea unida al final de la cadena ... debes deshacerte de ella ...

+-+-+-+--+--+ |b|o|b|/n|/0| +-+-+-+--+--+

Para deshacerse de la nueva línea haz esto. CAVEATS: No use "strlen (aName) - 1", ya que una línea devuelta por fgets puede comenzar con el carácter NUL, por lo que el índice en el búfer se convierte en -1:

aName[strcspn(aName, "/n")] = ''/0''; +-+-+-+--+ |b|o|b|/0| +-+-+-+--+

Ahora, strcmp debería devolver 0 ...