Luixx (Normal User)
Newbie
Messaggi: 8
Iscritto: 04/04/2016
|
Salve, ho questo menu che se inserisco i numeri interi non da nessun problema.. il problema se inserisco per caso una lettera (tipo: d)
mi va in loop il menu e lo ripete tante volte .. come faccio ad risolvere questo problema?
ecco il main:
Codice sorgente - presumibilmente C++ |
int main(void) { int sel_menu; do { menu(); scanf("%d", &sel_menu); printf("\n"); switch(sel_menu) { case 1: printf("Addizione \n "); inserisci_dati(); stampa_risultato('a', a,b); break; case 2: printf("Sottrazione \n "); inserisci_dati(); stampa_risultato('s', a,b); break; case 3: printf("Moltiplicazione \n "); inserisci_dati(); stampa_risultato('m', a,b); break; case 4: printf("Dividendo \n "); inserisci_dati(); stampa_risultato('d', a,b); break; case 6: inserisci_dati(); stampa_risultato('t',a,b); break; default: ; } } while(sel_menu != 5); return 0; }
|
avete idea? grazie mille.
|
|
Poggi Marco (Member)
Guru
Messaggi: 969
Iscritto: 05/01/2010
|
Ciao !
Il tuo problema sta nella funzione scanf("%d", &sel_menu). Infatti se non riconosce un numero intero, sel_menu non viene modificato, con conseguenze inattese sul programma.
Per ovviare a ciò esegui un controllo sull'input.
|
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Il problema è quello che dice Marco, purtroppo la questione della validazione dell'input può diventare complessa a piacere a seconda di quanto controllo sugli errori vuoi.
Nel tuo caso, visto che la voce del menu è di un carattere soltanto, ti conviene usare getchar() e poi controllare con isdigit() se è un numero (per isdigit includi <ctypes.h> ) . Se invece arrivi ad avere numeri più grandi di dieci conviene fare una cosa generale: usi fgets() per leggere, fgets si ferma quando trova il newline oppure se raggiunge il numero massimo di caratteri che indichi tu. I numeri interi signed arrivano fino a 2^31-1, che in decimale sono su per giù 9 caratteri. quindi:
Codice sorgente - presumibilmente C/C++ |
char input_string[20]; // basterebbe 9+1 per il terminatore, ma meglio stare larghi fgets(input_string, 20, stdin);
|
A questo punto puoi verificare che la stringa sia effettivamente un numero. Oppure usi direttamente la funzione atoi() (<stdlib.h> che converte la stringa in intero. Trovi tutte le funzioni che ho nominato con una ricerca su google.
Ultima modifica effettuata da lumo il 02/05/2016 alle 20:40 |
|
Mattia99 (Member)
Rookie
Messaggi: 38
Iscritto: 19/02/2016
|
Ciao! Volevo darti una soluzione più semplice per il tuo problema che, come avrai capito, è legato all'input dell'utente.
Se non sbaglio la scanf restituisce 1 quando l'input è un intero.
In questo caso ti basterà un semplice ciclo di controllo:
Codice sorgente - presumibilmente C/C++ |
while (scanf("%d", &sel_menu) != 1) {
printf("Inserisci un'intero: \n");
fflush(stdin);
scanf("%d",&sel_menu);
}
|
Non vorrei sbagliare, ma credo dovrebbe funzionare cosi..
|
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Postato originariamente da Mattia99: Ciao! Volevo darti una soluzione più semplice per il tuo problema che, come avrai capito, è legato all'input dell'utente. Se non sbaglio la scanf restituisce 1 quando l'input è un intero. In questo caso ti basterà un semplice ciclo di controllo:
Codice sorgente - presumibilmente C/C++ |
while (scanf("%d", &sel_menu) != 1) { printf("Inserisci un'intero: \n"); fflush(stdin); scanf("%d",&sel_menu); }
|
Non vorrei sbagliare, ma credo dovrebbe funzionare cosi.. |
Tecnicamente fflush non funziona su FILE aperti in input. So che la libreria standard che va con visual studio lo fa, ma non è così su altri sistemi. A parte questo la soluzione è corretta anche se lo scanf in più non è molto elegante. Il vantaggio di usare fgets è che si evitano tutti i problemi di buffering che si hanno con scanf.
|
|
Mattia99 (Member)
Rookie
Messaggi: 38
Iscritto: 19/02/2016
|
Non mi sembra che ci siano dei file aperti in input, quindi il fflush tecnicamente dovrebbe andare bene..
Ho solo proposto una soluzione più semplice (a parere mio) di quella proposta da te anche se meno elegante
|
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Postato originariamente da Mattia99:
Non mi sembra che ci siano dei file aperti in input, quindi il fflush tecnicamente dovrebbe andare bene..
Ho solo proposto una soluzione più semplice (a parere mio) di quella proposta da te anche se meno elegante |
Infatti nulla in contrario alla tua soluzione
Riguardo a fflush, forse saprai che il C si è sviluppato insieme ad UNIX. Su UNIX vale la filosofia "tutto è un file". Di fatto anche in C sia i file che apri con fopen che le variabili globali stdin/stdout/stderr sono di tipo FILE*, e puoi usarci le funzioni di stdio.h in modo del tutto indipendente dal tipo effettivo di file che ci sta dietro.
stdin è un FILE* dove si legge (quindi input), e dunque fflush non funziona. |
|
Luixx (Normal User)
Newbie
Messaggi: 8
Iscritto: 04/04/2016
|
Postato originariamente da Mattia99:
Ciao! Volevo darti una soluzione più semplice per il tuo problema che, come avrai capito, è legato all'input dell'utente.
Se non sbaglio la scanf restituisce 1 quando l'input è un intero.
In questo caso ti basterà un semplice ciclo di controllo:
Codice sorgente - presumibilmente C/C++ |
while (scanf("%d", &sel_menu) != 1) {
printf("Inserisci un'intero: \n");
fflush(stdin);
scanf("%d",&sel_menu);
}
|
Non vorrei sbagliare, ma credo dovrebbe funzionare cosi.. |
ok, ragazzi. ma che punto la devo mettere ? Perché se la metto dentro al do while e se testo mi ripete le cose all'infinito.
Per caso ho sbagliato ad scrivere il menu?
Grazie mille. |
|
Mattia99 (Member)
Rookie
Messaggi: 38
Iscritto: 19/02/2016
|
Se vuoi adottare la mia soluzione devi inserire la parte di codice che ti ho scritto subito dopo la scanf("%d",&sel_menu) Quella che hai scritto dopo menu()
|
|