Question Comparer les caractères saisis par l'utilisateur en C


Les extraits de code suivants proviennent d'un programme C.

L'utilisateur entre Y ou N.

char *answer = '\0';

scanf (" %c", answer);

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

Je n'arrive pas à comprendre pourquoi if déclaration n'évalue pas à vrai.

J'ai vérifié pour l'entrée y ou n avec un printf et il est là, donc je sais que je reçois la saisie de l'utilisateur. Aussi, lorsque je remplace la condition de l'instruction if par 1 (la rendant vraie), elle est évaluée correctement.


15
2017-10-12 04:18


origine


Réponses:


Je vois deux problèmes:

Le pointeur answer est un null pointeur et vous essayez de le déréférencer dans scanf, cela mène à comportement indéfini.

Vous n'avez pas besoin d'un char pointeur ici. Vous pouvez simplement utiliser un char variable comme:

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

Suivant pour voir si le caractère lu est 'y' ou 'Y' tu devrais faire:

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

Si vous vraiment besoin d'utiliser un pointeur de caractère, vous pouvez faire quelque chose comme:

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

22
2017-10-12 04:23



answer ne devrait pas être un pointeur, l'intention est évidemment de tenir un personnage. scanf prend l'adresse de ce personnage, il faut donc l'appeler comme

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

Ensuite, votre instruction "ou" est formée de manière incorrecte.

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

Ce que vous avez écrit à l'origine demande à comparer answer avec le résultat de 'Y' || 'y', ce que je devine n'est pas tout à fait ce que vous vouliez faire.


9
2017-10-12 04:19



Pour commencer, votre answer la variable doit être de type char, ne pas char*.

En ce qui concerne la if déclaration:

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

Ceci est la première évaluation 'Y' || 'y' qui, dans la logique booléenne (et pour ASCII), est vraie car les deux sont "true" (non nul). En d'autres termes, vous n'obtiendrez que le if déclaration à tirer si vous avez en quelque sorte entré CTRLUNE (encore une fois, pour ASCII, et où une valeur vraie équivaut à 1)*une.

Toi pourrait utiliser le plus correct:

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

mais vous devriez vraiment utiliser:

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

puisque c'est le moyen le plus portable d'atteindre le même objectif.


*une Vous vous demandez peut-être pourquoi je mets toutes sortes de conditionnels pour mes déclarations. Alors que la grande majorité des implémentations C utilisent des valeurs ASCII et certaines valeurs connues, elles ne sont pas forcément imposées par les normes ISO. Je sais pertinemment qu'au moins un compilateur utilise encore EBCDIC, donc je n'aime pas faire des hypothèses injustifiées.


5
2017-10-12 04:29



Parce que la comparaison ne fonctionne pas de cette façon. 'Y' || 'y' est un opérateur logique ou un opérateur; il retourne 1 (true) si l'un de ses arguments est vrai. Depuis 'Y' et 'y' sont tous deux vrais, vous comparez *answer avec 1.

Ce que vous voulez est if(*answer == 'Y' || *answer == 'y') ou peut-être:

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

5
2017-10-12 04:21