Comparación de caracteres ingresados ​​por el usuario en C

3 minutos de lectura

avatar de usuario
joe scho

Los siguientes fragmentos de código son de un programa C.

El usuario ingresa Y o N.

char *answer="\0";

scanf (" %c", answer);

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

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

Revisé la entrada y o n con un printf y está ahí, así que sé que estoy recibiendo la entrada del usuario. Además, cuando reemplazo la condición de la declaración if con 1 (haciéndola verdadera), se evalúa correctamente.

avatar de usuario
coadicto

Veo dos problemas:

el puntero answer es un null puntero y está tratando de desreferenciarlo en scanfesto lleva a comportamiento indefinido.

no necesitas un char puntero aquí. Solo puedes usar un char variables como:

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

Siguiente para ver si el carácter de lectura es 'y' o 'Y' deberías hacer:

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

Si tu De Verdad necesita usar un puntero de caracteres, puede hacer algo como:

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

  • ¿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.

    – corazonada

    11/08/2015 a las 13:50

  • @hunch Desde la página del manual (scanf (3): [… for type modifier character “c”…] Se suprime el salto habitual de espacio en blanco inicial. Para omitir el espacio en blanco primero, use un espacio explícito en el formato. […] Supongo que a su flujo de entrada le quedan algunos espacios que aparecen cuando accede al flujo, por lo que “se salta” su scanf. Supongo que ya te diste cuenta…

    – Haini

    9 de enero de 2016 a las 17:16

avatar de usuario
marca eliot

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

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

A continuación, su declaración “o” está formada incorrectamente.

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

Lo que escribiste originalmente pide comparar answer con el resultado de 'Y' || 'y'que supongo que no es exactamente lo que querías hacer.

  • Lo cambié, pero por alguna razón, el cuerpo de la instrucción if aún no se evalúa.

    – Joe Scho

    12 de octubre de 2010 a las 4:21

  • @Joe, tuvo un pequeño error tipográfico con un paréntesis adicional, si copió y pegó mi respuesta, probablemente habría fallado.

    – Mark Elliot

    12 de octubre de 2010 a las 4:22

avatar de usuario
paxdiablo

Para empezar, su answer la variable debe ser del tipo charno char*.

En cuanto a if declaración:

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

Esto es primero evaluar 'Y' || 'y' lo cual, en lógica booleana (y para ASCII) es verdadero ya que ambos son “verdaderos” (distintos de cero). En otras palabras, sólo obtendrías la if declaración para disparar si de alguna manera hubieras ingresado CONTROLUN (nuevamente, para ASCII, y donde los valores verdaderos equivalen a 1)*un.

podría Usa la más correcta:

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

pero realmente deberías estar usando:

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

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


*un Quizás se pregunte por qué estoy poniendo todo tipo de condicionales para mis declaraciones. Si bien la gran mayoría de las implementaciones de C usan ASCII y ciertos valores conocidos, los estándares ISO no lo exigen necesariamente. Sé con certeza que al menos un compilador todavía usa EBCDIC, por lo que no me gusta hacer suposiciones injustificadas.

avatar de usuario
Hobbs

Porque la comparación no funciona de esa manera. 'Y' || 'y' es un operador lógico o; vuelve 1 (verdadero) si alguno de sus argumentos es verdadero. Ya que 'Y' y 'y' ambos son ciertos, estás comparando *answer con 1

lo que quieres es if(*answer == 'Y' || *answer == 'y') o quizás:

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad