2010-10-12 10 views
15

Los siguientes fragmentos de código son de un programa en C.Comparación de caracteres ingresados ​​por el usuario en C

El usuario introduce Y o N.

char *answer = '\0'; 

scanf (" %c", answer); 

if (*answer == ('Y' || 'y')) 
    // do work 

No puedo entender por qué esta declaración if no se evalúa como verdadera.

Comprobé la entrada y o n con un printf y está allí, así que sé que estoy obteniendo la entrada del usuario. También cuando reemplazo la condición de la declaración if por 1 (que es verdadera), se evalúa correctamente.

Respuesta

22

veo dos problemas:

answer El puntero es un null Puntero y está intentando desreferenciarlo en scanf, esto lleva a comportamiento indefinido.

No necesita un puntero char aquí. Usted sólo puede usar una variable char como:

char answer; 
scanf(" %c",&answer); 

siguiente para ver si el personaje de lectura es 'y' o 'Y' que debe hacer:

if(answer == 'y' || answer == 'Y') { 
    // user entered y or Y. 
} 

Si realmente necesita usar un puntero char se puede hacer algo como:

char var; 
char *answer = &var; // make answer point to char variable var. 
scanf (" %c", answer); 
if(*answer == 'y' || *answer == 'Y') { 
+1

.. o llamando a 'malloc()' – Arun

+0

@ArunSaha: sí, o haz que apunte a una variable local char. – codaddict

+0

¿por qué es necesario poner un espacio antes de% c en scanf? para mí no funciona si elimino el espacio antes de% c en scanf. – hunch

9

answer no debe ser un puntero, la intención es obviamente mantener un carácter. scanf toma la dirección de este personaje, por lo que debe ser llamado como

char answer; 
scanf(" %c", &answer); 

A continuación, el "o" la declaración se forma incorrecta.

if (answer == 'Y' || answer == 'y') 

Lo que escriba pide originalmente para comparar answer con el resultado de 'Y' || 'y', que supongo no es exactamente lo que quería hacer.

+0

Lo cambié pero por alguna razón el cuerpo de la declaración if aún no está evaluando –

+0

@Joe, tenía un ligero error tipográfico con un par adicional, si copiaba y pegaba mi respuesta, probablemente habría fallado. –

+0

sí capté el error tipográfico, gracias –

5

Porque la comparación no funciona de esa manera. 'Y' || 'y' es un operador lógico u operador; devuelve 1 (verdadero) si alguno de sus argumentos es verdadero. Desde 'Y' y 'y' son ambas verdaderas, que está comparando con *answer 1.

Lo que queremos es if(*answer == 'Y' || *answer == 'y') o tal vez:

switch (*answer) { 
    case 'Y': 
    case 'y': 
    /* Code for Y */ 
    break; 
    default: 
    /* Code for anything else */ 
} 
5

Para empezar, su answer VA riable debe ser del tipo char, no char*.

En cuanto a la declaración if:

if (answer == ('Y' || 'y')) 

Esta es la primera evaluando 'Y' || 'y' el que, en la lógica booleana (y para ASCII) es cierto, ya que ambos son "verdadero" (distinto de cero).En otras palabras, sólo se obtendría la declaración if al fuego si lo ha introducido alguna manera CTRLUn (de nuevo, para ASCII, y donde unos verdaderos valores equivale a 1) * un.

Usted podría utilizan la más correcta:

if ((answer == 'Y') || (answer == 'y')) 

pero que realmente debería estar usando:

if (toupper(answer) == 'Y') 

ya que es la forma más portátil para lograr el mismo fin.


* a Es posible que se pregunte por qué estoy poniendo en todo tipo de condicionales para mis declaraciones. Si bien la gran mayoría de las implementaciones de C usan ASCII y ciertos valores conocidos, no es obligatorio según los estándares ISO. Sé con certeza que al menos un compilador todavía usa EBCDIC, así que no me gusta hacer suposiciones injustificadas.

Cuestiones relacionadas