Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - problema menu
Forum - C/C++ - problema menu

Pagine: [ 1 2 3 ] Precedente | Prossimo
Avatar
Luixx (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/04/2016

Segnala al moderatore
Postato alle 18:30
Lunedì, 02/05/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++

  1. int main(void)
  2. {
  3.     int sel_menu;
  4.  
  5.     do {
  6.       menu();
  7.       scanf("%d", &sel_menu);
  8.       printf("\n");
  9.       switch(sel_menu) {
  10.       case 1:
  11.         printf("Addizione \n ");
  12.         inserisci_dati();
  13.         stampa_risultato('a', a,b);
  14.         break;
  15.       case 2:
  16.         printf("Sottrazione \n ");
  17.         inserisci_dati();
  18.         stampa_risultato('s', a,b);
  19.         break;
  20.       case 3:
  21.         printf("Moltiplicazione \n ");
  22.         inserisci_dati();
  23.         stampa_risultato('m', a,b);
  24.         break;
  25.       case 4:
  26.         printf("Dividendo \n ");
  27.         inserisci_dati();
  28.         stampa_risultato('d', a,b);
  29.         break;
  30.       case 6:
  31.         inserisci_dati();
  32.         stampa_risultato('t',a,b);
  33.           break;
  34.       default: ;
  35.         }
  36.       } while(sel_menu != 5);
  37.    return 0;
  38. }



avete idea? grazie mille.

PM Quote
Avatar
Poggi Marco (Member)
Guru


Messaggi: 950
Iscritto: 05/01/2010

Segnala al moderatore
Postato alle 19:05
Lunedì, 02/05/2016
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.


Nulla va più veloce della luce, quindi rilassati.
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 414
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 20:40
Lunedì, 02/05/2016
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++

  1. char input_string[20]; // basterebbe 9+1 per il terminatore, ma meglio stare larghi
  2. 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
PM Quote
Avatar
Mattia99 (Member)
Rookie


Messaggi: 38
Iscritto: 19/02/2016

Segnala al moderatore
Postato alle 20:45
Lunedì, 02/05/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++

  1. while (scanf("%d", &sel_menu) != 1) {
  2.       printf("Inserisci un'intero: \n");
  3.       fflush(stdin);
  4.       scanf("%d",&sel_menu);
  5.    }



Non vorrei sbagliare, ma credo dovrebbe funzionare cosi..:k:


«Mi farebbe piacere cambiare il mondo, ma non mi danno il suo codice sorgente.»
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 414
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 21:07
Lunedì, 02/05/2016
Testo quotato

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++

  1. while (scanf("%d", &sel_menu) != 1) {
  2.       printf("Inserisci un'intero: \n");
  3.       fflush(stdin);
  4.       scanf("%d",&sel_menu);
  5.    }



Non vorrei sbagliare, ma credo dovrebbe funzionare cosi..:k:



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.

PM Quote
Avatar
Mattia99 (Member)
Rookie


Messaggi: 38
Iscritto: 19/02/2016

Segnala al moderatore
Postato alle 21:22
Lunedì, 02/05/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:k::)


«Mi farebbe piacere cambiare il mondo, ma non mi danno il suo codice sorgente.»
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 414
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 21:36
Lunedì, 02/05/2016
Testo quotato

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:k::)


Infatti nulla in contrario alla tua soluzione :k:

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.

PM Quote
Avatar
Luixx (Normal User)
Newbie


Messaggi: 8
Iscritto: 04/04/2016

Segnala al moderatore
Postato alle 21:47
Lunedì, 02/05/2016
Testo quotato

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++

  1. while (scanf("%d", &sel_menu) != 1) {
  2.       printf("Inserisci un'intero: \n");
  3.       fflush(stdin);
  4.       scanf("%d",&sel_menu);
  5.    }



Non vorrei sbagliare, ma credo dovrebbe funzionare cosi..:k:



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.

PM Quote
Avatar
Mattia99 (Member)
Rookie


Messaggi: 38
Iscritto: 19/02/2016

Segnala al moderatore
Postato alle 22:39
Lunedì, 02/05/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()


«Mi farebbe piacere cambiare il mondo, ma non mi danno il suo codice sorgente.»
PM Quote
Pagine: [ 1 2 3 ] Precedente | Prossimo