Controllo dati immessi dall'utente

di Anonimizzato7887 il
7 risposte
Ciao a tutti, ho scritto un semplice programma che chiede in ingresso un float e poi ci fa varie cose (non importanti per il problema).
Io lo leggo così
scanf("%g", &x)
. Tutto funziona perfettamente se l'utente sa che deve usare "." come separatore per i decimali, perchè se usa "," succede un macello e il programma crasha malamente...
C'è un modo per evitare tutto questo, magari facendo qualche tipo di controllo preliminare?
Grazie!

7 Risposte

  • Return Value
    On success, the function returns the number of items successfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.
    quindi puoi verificare se scanf ti ritorna 1 se è riuscito a leggere il valore oppure no.
  • Grazie!
    Ci si ritrova... vedo che ti hanno fatto moderatore. Beh direi che è più che giusto!!!
  • Rieccomi... ho modificato il codice così:
    
    ...
    float x;
    int result;
    printf("Inserire il valore iniziale: ");
    result = scanf("%g", &x);
    if(result > 0) {
           ...resto del codice...
    }
    
    ma il problema rimane, perchè è come se il controllo venisse fatto troppo tardi.
    Come posso risolvere?
  • La scanf non è indicata per questo tipo di controllo. Può tuttavia controllare delle stringhe anche se a mio avviso è abbastanza insicura come soluzione in quanto rimane sporco il buffer nella parte incorretta.btw giyf
    Il modo migliore per affrontare il problema è usare un buffer di char letto da una fgets e fare i relativi controlli di validità e poi filtrare il tutto attraverso una sscanf. Ti allego un pezzo di codice chiarificatore estratto e leggermente modificato da
    
    #include <stdio.h>
    #include <string.h>
    int getvalue (char *format,void *value)
    {
      static char *values=" .+-0123456789";  
      int ExitCode=0,len=0;
      
      #define MAXSIZE 64
      char s[MAXSIZE];
      
      if (fgets (s,MAXSIZE,stdin))
    	len=strlen(s)-1;
    	
      for (--len;!ExitCode && len>=0 ;len--)
        if (!strchr (values,s[len]))
            ExitCode=1;
    
      if (!ExitCode)
    	sscanf (s,format,value);
      
      return ExitCode;
    }
    
    int main ()
    {
    
      int result;
      float x;
      
      printf("Inserire il valore iniziale: ");
      while (1)
      {
    	result=getvalue ("%g",&x);
    	printf ("result is %s x=%g\n",(!result)?"OK":"ERROR",x);
      }
    
      return 0;
    }
    
  • Wow, tutta sta roba??
    mi sa che metterò un bel
    
    printf("Inserire il valore iniziale: (usare . come separatore!!!)");
    
    e poi se l'utonto si sbaglia sono fatti suoi
  • Io proverei così:
    
    while(scanf("%s",validity)==0); //esegue lo scanf() fino a che non è valido
    int pos=strcspn(validity,","); con strcpos trovo la lunghezza della stringa iniziale NON contenente "," , e quindi la posizione della virgola
    if pos!=strlen(validity)validity[pos]='.'; //se trovo la virgola, la sostituisco col punto
    sscanf(validity,%f,&number); //leggo il numero
    
    Prova vedi se così funziona.
  • Perfetto! così funziona senza problemi.
    grazie mille!
Devi accedere o registrarti per scrivere nel forum
7 risposte