PDA

Visualizza la versione completa : [C] Scanf e scelta di un'opzione da input - loop infinito


tigerjack89
15-02-2012, 17:03
Ciao a tutti.
Mi sto inceppando su un problema che a prima vista sembrerebbe banale, e comunque aggirabile, ma vorrei capire a cosa è dovuto il mio errore. In pratica, la funzione main stampa su OUTPUT (di default è stdout), una lista di scelte possibili; dopodichè si prende in input con una scanf il valore scelto e lo si assegna alla variabile choice. Quindi, si switcha la choice e si eseguono le operazioni corrispondenti.
In pratica, però, se da input digito la 'q' per uscire, mi va in loop infinito, continuando a stampare sempre le opzioni disponibili, con alla fine "Unvalid choice"; ricade, quindi, sempre nella condizione di default. Inoltre, succede lo stesso anche se digito qualunque altro carattere da tastiera.
Ciò non accade, invece, se inserisco un numero da tastiera; se il numero non è presente tra le varie opzioni, mi stampa unvalid choice e di nuovo le opzioni, consentendomi di scegliere un'altra opzione.


int main()
{
int choice, value, quit = 0;

while (!quit)
{
fputs("Insert a number to choice an option: \n", OUTPUT);
fputs("1 Add an element at the head\n", OUTPUT);
fputs("2 Add an element at the end\n", OUTPUT);
// [...]
fputs("q Exit\n", OUTPUT);
fputs("\n\n", OUTPUT);

scanf("%d", &choice);
switch (choice)
{
case 1:
// [...]
break;
case 2:
// [...]
break;
// [...altri case...]
case 'q':
fputs("Exit\n", OUTPUT);
quit = 1;
break;
default:
fputs("Unvalid choice\n", OUTPUT);
break;
}
}
}

Come mai? Come si può risolvere?

oregon
15-02-2012, 17:12
Non puoi rispondere con una lettera ad un input numerico.

E una variabile numerica non può memorizzare caratteri.

tigerjack89
15-02-2012, 17:14
Originariamente inviato da oregon
Non puoi rispondere con una lettera ad un input numerico.

E una variabile numerica non può memorizzare caratteri.
Ok ma il valore di un carattere, come la 'q' dell'esempio, non è un intero? Non viene passato come intero?

oregon
15-02-2012, 17:18
No ... la scanf tenta di ottenere il tipo di dato indicato

%d

e la q non è convertibile in un numero.

Semmai la q ha un corrispondente valore ASCII ma non c'entra in questo caso.

Se vuoi utilizzare un carattere, allora usa lo switch

%c

oppure accetta una stringa

%s

ed esaminala per decidere quale input è stato fornito. Ovviamente con il tipo di variabile opportuna.

tigerjack89
15-02-2012, 17:25
Cioè in pratica potrei fare qualcosa del tipo


char string[100];
char choiceC
int choiceN;

while ( gets(string) != NULL)
if ( sscanf(string, "%d", &choiceN) == 1) //allora è un numero e lo switcho
//....
else if ( sscanf(string, "%c", &choiceC) == 1) //allora è un carattere
//controllo se è il carettere di uscita....
else
//opzione non valida

oregon
15-02-2012, 17:26
Se l'input è fatto da un solo carattere 1 2 q allora ti basta la

scanf("%c", &varchar),


(ma occhio al problema del buffer di tastiera)

tigerjack89
15-02-2012, 17:28
Originariamente inviato da oregon
Se l'input è fatto da un solo carattere 1 2 q allora ti basta la

scanf("%c", &varchar),

Giusto!! In pratica, invece di prendere in input un intero, prendo un carattere e lo switcho. Cosa accade però a quel punto se invece di un carattere l'utente inserisce una stringa??



(ma occhio al problema del buffer di tastiera)

In che senso?

oregon
15-02-2012, 17:30
Comincia a scrivere il codice, provalo e poi si vede ...

tigerjack89
15-02-2012, 17:38
Originariamente inviato da oregon
Comincia a scrivere il codice, provalo e poi si vede ...
Se inserisco una stringa, ovviamente mi ricade nel caso di default (o in quello di uscita) analizzando un carattere alla volta,
Se invece inserisco un carattere compreso nei casi dello switch, mi esegue prima le istruzioni dello switch, alla fine ricade nel caso di default e poi mi permette di inserire un nuovo input.

In pratica, ecco qui l'output se provo a digitare '5'

Insert a number to choice an option:
1 Add an element at the head
2 Add an element at the end
3 Extract first value
4 Extract last value
5 Print list
q Exit


5

LIST
List is empty
Insert a number to choice an option:
1 Add an element at the head
2 Add an element at the end
3 Extract first value
4 Extract last value
5 Print list
q Exit


*****Unvalid choice******

Insert a number to choice an option:
1 Add an element at the head
2 Add an element at the end
3 Extract first value
4 Extract last value
5 Print list
q Exit

oregon
15-02-2012, 17:45
Ma serve che mostri il nuovo codice, non solo il risultato ...

Per esempio, dato che adesso il dato in input è un carattere, i case saranno

'1'

'2'

'q'


e così via ... hai scritto in questo modo?

Loading