2010-10-12 18 views
15

I seguenti frammenti di codice provengono da un programma C.Confronto di caratteri immessi dall'utente in C

L'utente immette Y o N.

char *answer = '\0'; 

scanf (" %c", answer); 

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

non riesco a capire perché questa affermazione if non restituisce vero.

Ho controllato l'input yo n con un printf ed è lì, quindi so che sto ricevendo l'input dell'utente. Anche quando sostituisco la condizione dell'istruzione if con 1 (rendendolo vero), valuta correttamente.

risposta

22

vedo due problemi:

Il puntatore answer è un null puntatore e si sta tentando di dereferenziarlo in scanf, questo porta al comportamento non definito .

Non è necessario un puntatore char qui. Si può semplicemente utilizzare una variabile char come:

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

successivo per vedere se il carattere di lettura è 'y' o 'Y' si dovrebbe fare:

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

Se davvero bisogno di utilizzare un puntatore char voi può fare qualcosa di simile:

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

.. o chiamando 'malloc()' – Arun

+0

@ArunSaha: sì, o puntare a una variabile char locale. – codaddict

+0

perché è necessario mettere uno spazio prima di% c in scanf? per me non funziona se rimuovo lo spazio prima di% c in scanf. – hunch

9

answer non deve essere un puntatore, l'intento è ovviamente quello di contenere un carattere. scanf prende l'indirizzo di questo personaggio, quindi dovrebbe essere chiamato come

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

Avanti, il vostro "o" dichiarazione è formato in modo non corretto.

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

Quello che hai scritto chiede originariamente per confrontare answer con il risultato di 'Y' || 'y', che sto cercando di indovinare non è proprio quello che si voleva fare.

+0

L'ho modificato ma per qualche motivo il corpo dell'istruzione if non sta ancora valutando –

+0

@Joe, ha avuto un leggero errore di battitura con un ulteriore paren, se è stato copiato e incollato dalla mia risposta probabilmente sarebbe fallito. –

+0

sì ho preso l'errore di battitura, grazie –

5

Perché il confronto non funziona in questo modo. 'Y' || 'y' è un operatore logico o; restituisce 1 (true) se uno dei suoi argomenti è vero. Dal momento che 'Y' e 'y' sono entrambe vere, si sta confrontando con *answer 1.

Quello che vuoi è if(*answer == 'Y' || *answer == 'y') o forse:

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

Per un inizio, il tuo answer va dovrebbe essere di tipo char, non char*.

Per quanto riguarda la dichiarazione if:

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

Questo è il primo valutando 'Y' || 'y' che, nella logica booleana (e per ASCII) è vero in quanto entrambi sono "vere" (non-zero).In altre parole, ci si ottiene solo la dichiarazione if al fuoco se si desidera in qualche modo entrato CTRLA (ancora una volta, per ASCII, e dove un vero valore equivale a 1) * un.

È potrebbe utilizzare il più corretto:

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

ma è davvero dovrebbe utilizzare:

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

dato che questo è il modo più portabile per raggiungere lo stesso fine.


* una Ci si potrebbe chiedere perché sto mettendo in tutti i tipi di condizionali per le mie affermazioni. Mentre la stragrande maggioranza delle implementazioni C utilizza ASCII e alcuni valori noti, non è obbligatoriamente prescritta dagli standard ISO. So per certo che almeno un compilatore usa ancora EBCDIC quindi non mi piace fare ipotesi ingiustificate.