Problema con costrutto if (C)

valentina921
Salve a tutti,
sto provando a scrivere un programma che simuli il gioco della roulette e sono incappata in un problema che non capisco da cosa possa essere dovuto.
Sto lavorando nel linguaggio C.
Metto solo la parte del listato che mi crea il problema(con opportune dichiarazioni, così se manca qualcosa vi accorgete).

#include
#include
#include

char pari_dispari ();

main () {

int a;
char b, e;

srand48(time(0));

printf ("Inserire 0 o 1: ");
scanf ("%d", &a);

if (a==1) {

printf ("\nAvete scelto di puntare pari o dispari.\n\nDigitare 'p' se si vuole puntare sui pari, 'd' se si vuole puntare sui dispari: ");
scanf ("%c", &b);

e = pari_dispari();

if (e==b) {
printf ("\nHai vinto!");
}
else {
printf ("\nHai perso!");
}
}
}


char pari_dispari () {
int b;
char a;
b = (lrand48()%2)+40;
if (b==40) {
a = 'p';
}
else {
a = 'd';
}
return a;
}

In questo modo la compilazione va a buon fine e il problema sta nell'esecuzione: il programma, dopo aver chiesto di digitare 'p' per i pari e 'd' per i dispari, stampa direttamente il messaggio "hai perso", senza far immettere la lettera da tastiera. Se invece tolgo l'if principale, quello con if(a==1), cioè faccio eseguire quello che sta dentro di esso indipendentemente dalla scelta dell'utente, l'esecuzione è esatta, cioè viene data la possibilità di inserire la lettera 'p' o 'd', e il messaggio stampato è "hai vinto" o "hai perso" in base a ciò che l'utente ha immesso da tastiera. Non capisco perchè, solo inserendo tutto ciò in un altro costrutto if non avviene.

Non so se sono stata chiara, nel caso non lo fossi stata proverò a spiegarmi meglio. Grazie in anticipo

Valentina

Risposte
ebrunaway
Stai guardando nella direzione sbagliata.
Il problema sono le due scanf in successione (o piu` in generale di alcune perversioni della scanf).
Alla prima invocazione la scanf guarda fino al carattere new-line senza pero` leggerlo realmente, e lo utilizza come input nella seconda invocazione. Viene impedito l'inserimento del secondo input e il messaggio relativo alla perdita e` tale in quanto la condizione e==b non potra` mai essere verificata, poiche` a b e` associato il carattere new-line.
Puoi risolverlo in diversi modi, uno tra i piu` immediati e` aggiungere all`inizio della seconda invocazione il carattere new-line
scanf ("\n%c", &b);
La tendenza attuale e` comunque quella di scoraggiare l`uso della scanf per altre tipo getchar().
Tra le altre cose, nota che il carattere new-line viene utilizzato come secondo input se la scanf acquisisce %c, mentre se si stanno trattando %d i new-line vengono ignorati e la computaizione procede senza errori(puoi fare una verifica diretta sul tuo codice dichiarando b come intero e modificando opportunamente la seconda scanf).

valentina921
Questa cosa non la sapevo, mi stavo scervellando! Ti ringrazio davvero molto, ho aggiunto \n alla scanf come hai scritto tu e adesso funziona tutto. Solo una precisazione, qual'è il \n che interpreta come carattere inserito? Ho provato a toglierne un po' per vedere se riuscivo a non mettere \n sulla scanf (solo per curiosità, lo avrei messo comunque poi per mettere tutti i \n che voglio) ma continua sempre a fare quel lavoro là di stampare il messaggio senza far immettere nulla..

ebrunaway
Alla prima scanf, quando devi immettere 0 o 1 in realta` quello che immetti e` la sequenza 0-INVIO, 1-INVIO. Quest'INVIO viene "visto" dalla scanf come carattere new-line '\n' ma non viene letto realmente e sara` usato come secondo input.
Per questo motivo se metti nella seconda scanf "\n%c", la scanf si aspetta un carattere new-line e successivamente un input di tipo char. Quindi quel new-line della prima scanf viene utilizzato nella seconda come primo input, e a quel punto il programma procede a dovere, restando in attesa del char.

valentina921
Perfetto, chiarissimo. Grazie ancora e buone feste!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.