2009-06-09 11 views
6

Sé que esto puede ser una pregunta totalmente novato (no he tocado C en mucho tiempo), pero alguien me puede decir por qué esto no está funcionando?strcmp no funciona

printf("Enter command: "); 
bzero(buffer,256); 
fgets(buffer,255,stdin); 

if (strcmp(buffer, "exit") == 0) 
    return 0; 

Si entro en la "salida" que no entra en el caso, tiene que ver con la longitud del "buffer"?

¿Alguna sugerencia?

Respuesta

18

que quieres hacer esto:

strcmp(buffer, "exit\n")

Es decir, cuando introduce su cadena y pulse "enter", el salto de línea se convierte en una parte de buffer.

Alternativamente, utilice strncmp(), que sólo compara n caracteres de la cadena

+4

Eso es bueno a menos que el usuario escriba un espacio antes o después de salir.Y no olvide la historia (probablemente apócrifa) del sistema que dejó de funcionar cuando se agregó Ecuador, la gente tuvo que escribir Quito por el nombre de la capital y el programa salió (se cerró) porque solo se compararon las primeras 4 letras con 'dejar'. Muy desagradable! –

+3

@Jonathan truths! Mi propia sugerencia es garantizar que el usuario nunca pueda ingresar nada en su programa. – poundifdef

9

fgets() devuelve la cadena "exit \ n" - a diferencia de gets(), conserva las líneas nuevas.

+0

... y "obtiene" solo toma un parámetro (búfer en este ejemplo). ¡Gracias! – juan

+8

(No use gets() en público.) – Dave

+0

@Dave ¿Por qué es eso? –

5

Como han dicho otros, comparando con "exit" está fallando debido a fgets() incluido el salto de línea en el búfer. Una de sus garantías es que el búfer terminará con una nueva línea, a menos que la línea ingresada sea demasiado larga para el búfer, en cuyo caso no termina con una nueva línea. fgets() también garantiza que el búfer está terminado nulo, por lo que no necesita cero 256 bytes, pero solo deje que fgets() use 255 para obtener esa garantía.

La respuesta fácil de comparar exactamente a "exit\n" requiere que el usuario no agregue accidentalmente espacios en blanco antes o después de la palabra. Eso puede no importar si desea forzar al usuario a tener cuidado con el comando salir, pero podría ser una fuente de molestia para el usuario en general.

El uso de strncmp() permite "exited", "exit42", y más para que coincida con los que no desee. Eso podría funcionar en su contra, especialmente si algunos comandos válidos son cadenas de prefijo de otros comandos válidos.

En el caso general, a menudo es una buena idea separar la E/S, la tokenización, el análisis sintáctico y la acción en sus propias fases.

+0

Uso: fgets (buffer, sizeof (buffer), fp); y no restar uno (o usa 255) porque fgets() se comporta sanamente: le dijiste cuánto espacio hay y garantiza que no use más, colocando el terminador nulo en el último carácter disponible en el conjunto. –

+0

Exactamente lo que estaba tratando de decir ... pero mejor dicho. ;-) – RBerteig

0

Te recomiendo que des la \ n del final de la cadena, así.

 
char buf[256]; 
int len; 
/* get the string, being sure to leave room for a null byte */ 
if (fgets(buf,sizeof(buf) - 1) == EOF) 
{ 
    printf("error\n"); 
    exit(1); 
} 
/* absolutely always null-terminate, the easy way */ 
buf[sizeof(buf) - 1] = '\0'; 
/* compute the length, and truncate the \n if any */ 
len = strlen(buf); 
while (len > 0 && buf[len - 1] == '\n') 
{ 
    buf[len - 1] = '\0'; 
    --len; 
} 

esta manera, si usted tiene que comparar la cadena introducida contra varias constantes, estás no tener que añadir el \ n a todos ellos.

+0

¿Por qué el voto a favor? Es una solución válida, aunque no se explica. –