Oppure

Loading
02/05/16 16:30
Luixx
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:

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.
aaa
02/05/16 17:05
Poggi Marco
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.
aaa
02/05/16 18:40
lumo
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:
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 02/05/16 18:40
aaa
02/05/16 18:45
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:
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..:k:
aaa
02/05/16 19:07
lumo
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:
while (scanf(&quot;%d&quot;, &amp;sel_menu) != 1) {
      printf(&quot;Inserisci un'intero: \n&quot;);
      fflush(stdin);
      scanf(&quot;%d&quot;,&amp;sel_menu);
   }

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.
aaa
02/05/16 19:22
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::)
aaa
02/05/16 19:36
lumo
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.
aaa
02/05/16 19:47
Luixx
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:
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..: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.
aaa