Piccolo problema da principiante.

di il
11 risposte

Piccolo problema da principiante.

Salve, sono un ragazzo e sto cercando di imparare il linguaggio c, ma sono ancora alle prime armi.
Mentre mi esercito scrivendo i miei "imbarazzanti" programmini mi capita di imbattermi in alcuni problemi, ad esempio scrivendo un programma che riceve in input alcuni numeri interi se inserisco un carattere incombo in errori non fatali cioè il programma risolve il problema a modo suo e con dati ricavati dal carattere! A questo punto la mia domanda è questa:
Come faccio ad evitare questo errore? Magari semplicemente visualizzando in output "per favore inserire un numero valido"

Grazie in anticipo.

11 Risposte

  • Re: Piccolo problema da principiante.

    olivitosal ha scritto:


    Salve, sono un ragazzo e sto cercando di imparare il linguaggio c, ma sono ancora alle prime armi.
    Mentre mi esercito scrivendo i miei "imbarazzanti" programmini mi capita di imbattermi in alcuni problemi, ad esempio scrivendo un programma che riceve in input alcuni numeri interi se inserisco un carattere incombo in errori non fatali cioè il programma risolve il problema a modo suo e con dati ricavati dal carattere! A questo punto la mia domanda è questa:
    Come faccio ad evitare questo errore? Magari semplicemente visualizzando in output "per favore inserire un numero valido"

    Grazie in anticipo.
    Se sai sicuramente che quel dato che deve essere inserito da un'utente è un numero dichiari la variabile con "int",poi non c'è numero valido e uno non valido,potresti spiegarmi meglio il problema?
  • Re: Piccolo problema da principiante.

    Wolt ha scritto:


    olivitosal ha scritto:


    Salve, sono un ragazzo e sto cercando di imparare il linguaggio c, ma sono ancora alle prime armi.
    Mentre mi esercito scrivendo i miei "imbarazzanti" programmini mi capita di imbattermi in alcuni problemi, ad esempio scrivendo un programma che riceve in input alcuni numeri interi se inserisco un carattere incombo in errori non fatali cioè il programma risolve il problema a modo suo e con dati ricavati dal carattere! A questo punto la mia domanda è questa:
    Come faccio ad evitare questo errore? Magari semplicemente visualizzando in output "per favore inserire un numero valido"

    Grazie in anticipo.
    Se sai sicuramente che quel dato che deve essere inserito da un'utente è un numero dichiari la variabile con "int",poi non c'è numero valido e uno non valido,potresti spiegarmi meglio il problema?
    Questo è ovvio. Però nel momento in cui vado a inserire l'intero da tastiera posso inserire (per sbaglio o altro) anche un carattere! a questo punto come ho detto c'è un errore non fatale!

    Ad esempio in un semplice programma che prende in input due interi e visualizza la sua somma:
    #include<stdio.h>
    #include<stdlib.h>
    
    int main(){
        int x ; /*primo numero intero*/
        int y ; /*secondo numero intero*/
        int z ; /*somma dei precedenti numeri interi*/
        
        
        printf("Inserire un numero intero:\n") ;
        scanf("%d",&x) ;
    
        printf("\nInserire un numero intero:\n") ;
        scanf("%d",&y) ;   
        
        z = x + y ;
        
        printf("La somma e' %d\n",z) ;
        
        system("pause") ;
        return 0 ;
    }     
    
    In questo programma una volta eseguito arriva il momento in cui devo inserire i due interi, a questo punto per "dispetto" inserisco un carattere e succede che il programma continua comunque visualizzando comunque una somma(errore non fatale).

    Quindi la mia domanda è questa:
    Posso evitare che ciò accade con qualche istruzione? Ad esempio se inserisco il carattere vorrei che uscisse una messaggio di errore o qualche altro avviso!


    Spero di essermi spiegato! Grazie
  • Re: Piccolo problema da principiante.

    Forse la funzione isdigit(int c) dovrebbe funzionare...
    Si trova nell'header ctype.h
  • Re: Piccolo problema da principiante.

    Capisco la tua voglia di voler sperimentare e rendere al meglio i primi programmi con cui si ha a che fare. Ma c'è tempo e tempo, per ora devi pensare alle somme, alle variabili e alle basi del C, poi quando diventerai più esperto ed andrai avanti, troverai da solo la soluzione. E' questo che ti da delle soddisfazioni.
  • Re: Piccolo problema da principiante.

    Live ha scritto:


    Capisco la tua voglia di voler sperimentare e rendere al meglio i primi programmi con cui si ha a che fare. Ma c'è tempo e tempo, per ora devi pensare alle somme, alle variabili e alle basi del C, poi quando diventerai più esperto ed andrai avanti, troverai da solo la soluzione. E' questo che ti da delle soddisfazioni.
    Quoto
  • Re: Piccolo problema da principiante.

    Light ha scritto:


    Forse la funzione isdigit(int c) dovrebbe funzionare...
    Si trova nell'header ctype.h
    no perché quella funzione controlla solo che c sia o una cifra da '0' a '9' oppure il codice ASCII dei caratteri '0' '1' ... '9', quindi se inserisci ad esempio 65 (codice ASCII di 'A') ritorna 0.

    Da quel che ne so io funzioni utili a questo scopo richiedono che il compilatore supporti il C99 (almeno quelle parti del C99 usate nelle funzioni stesse): un esempio mi pare sia nscanf(), che richiede come paramentro aggiuntivo il numero di caratteri digitati che devono essere considerati e convertiti secondo la stringa di formato (ma non sono sicuro, vado a memoria); nel nostro caso non sarebbe molto utile ma in altri sì.

    Invece restando all' ANSI C potresti usare un ciclo tipo:
    
    int numero[9]={0};
    int i=0;
    int msd;
    int pos=1;
    int number=0;
    ...
    while(isdigit(numero[i]=getchar()) && numero[8]<2 && i<=8)     i++;
    
    if(!isdigit(numero[i])     msd=i-1;
    else     msd=i;
    
    for(i=0; i=msd; i++) {
         number+=numero[i]*pos;
         pos*=10;
    }
    
    Purtroppo così perdi la possibilità di potre inserire numeri da 1999999999 fino al massimo signed int.

    ma non so se ci sono soluzioni migliori, né all'università né sui libri ho trovato molto a riguardo, a parte quella cosa del C99.
  • Re: Piccolo problema da principiante.

    dvaosta ha scritto:


    Light ha scritto:


    Forse la funzione isdigit(int c) dovrebbe funzionare...
    Si trova nell'header ctype.h
    no perché quella funzione controlla solo che c sia o una cifra da '0' a '9' oppure il codice ASCII dei caratteri '0' '1' ... '9', quindi se inserisci ad esempio 65 (codice ASCII di 'A') ritorna 0.

    Da quel che ne so io funzioni utili a questo scopo richiedono che il compilatore supporti il C99 (almeno quelle parti del C99 usate nelle funzioni stesse): un esempio mi pare sia nscanf(), che richiede come paramentro aggiuntivo il numero di caratteri digitati che devono essere considerati e convertiti secondo la stringa di formato (ma non sono sicuro, vado a memoria); nel nostro caso non sarebbe molto utile ma in altri sì.

    Invece restando all' ANSI C potresti usare un ciclo tipo:
    
    int numero[9]={0};
    int i=0;
    int msd;
    int pos=1;
    int number=0;
    ...
    while(isdigit(numero[i]=getchar()) && numero[8]<2 && i<=8)     i++;
    
    if(!isdigit(numero[i])     msd=i-1;
    else     msd=i;
    
    for(i=0; i=msd; i++) {
         number+=numero[i]*pos;
         pos*=10;
    }
    
    Purtroppo così perdi la possibilità di potre inserire numeri da 1999999999 fino al massimo signed int.

    ma non so se ci sono soluzioni migliori, né all'università né sui libri ho trovato molto a riguardo, a parte quella cosa del C99.
    Basta utilizzare un infinità di istruzioni if...else per non far comparire le lettere
    Certo, sono tante istruzioni, tante quante sono le lettere dell'alfabeto più i caratteri speciali, però rimane in C.
  • Re: Piccolo problema da principiante.

    Ma scusatemi
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void simplegetline(char* line)
    {
        while ( (*line++ = getchar()) != '\n');
        *(--line)='\0';
    }
    
    int isint(char *cnum)
    {
        for (; *cnum != '\0' ;cnum++)
            if ( *cnum < '0' || *cnum > '9' ) return 0;
        return 1;
    }
    
    int main()
    {
        printf("Hello world?\n");
    
        char line[80];
    
        do
        {
            printf("Insert first number:");
            simplegetline(line);
        }while(!isint(line));
    
        int n1=atoi(line);
    
        do
        {
            printf("Insert second number:");
            simplegetline(line);
        }while(!isint(line));
    
        int n2=atoi(line);
    
        printf("%d + %d = %d\n",n1,n2,n1+n2);
        return 0;
    }
    
  • Re: Piccolo problema da principiante.

    vbextreme ha scritto:


    ma scusatemi
    
    #include <stdio.h>
    #include <stdlib.h>
    
    void simplegetline(char* line)
    {
        while ( (*line++ = getchar()) != '\n');
        *(--line)='\0';
    }
    
    int isint(char *cnum)
    {
        for (; *cnum != '\0' ;cnum++)
            if ( *cnum < '0' || *cnum > '9' ) return 0;
        return 1;
    }
    
    int main()
    {
        printf("Hello world?\n");
    
        char line[80];
    
        do
        {
            printf("Insert first number:");
            simplegetline(line);
        }while(!isint(line));
    
        int n1=atoi(line);
    
        do
        {
            printf("Insert second number:");
            simplegetline(line);
        }while(!isint(line));
    
        int n2=atoi(line);
    
        printf("%d + %d = %d\n",n1,n2,n1+n2);
        return 0;
    }
    
    Dovrebbe andare, forse però hai scordato le parentesi intorno a line++ nella prima funzione.
    A parte questo hai incrementato/decrementato l'indirizzo di line, che però è il nome di un array e quindi punta ad un indirizzo costante (avresti dovuto creare un altro puntatore al primo elemento del file e poi farlo scorrere, riportandolo all'inizio alla fine di simplegetline() per far sì che sia pronto anche per la seconda chiamata (oppure crei il puntatore dentro la funzione); infine, non capisco perché creare un vettore da 80 caratteri quando gli int tipicamente arrivano fino ai migliardi (qui non sono dichiarati long), quindi basterebbero 11 caratteri.
  • Re: Piccolo problema da principiante.

    Ok, mi limito ad aspettare
    Grazie.
  • Re: Piccolo problema da principiante.

    Dovrebbe andare, forse però hai scordato le parentesi intorno a line++ nella prima funzione.
    A parte questo hai incrementato/decrementato l'indirizzo di line, che però è il nome di un array e quindi punta ad un indirizzo costante (avresti dovuto creare un altro puntatore al primo elemento del file e poi farlo scorrere, riportandolo all'inizio alla fine di simplegetline() per far sì che sia pronto anche per la seconda chiamata (oppure crei il puntatore dentro la funzione); infine, non capisco perché creare un vettore da 80 caratteri quando gli int tipicamente arrivano fino ai migliardi (qui non sono dichiarati long), quindi basterebbero 11 caratteri.
    *line++
    prende valore puntato dalla variabile e muovo l'indirizzo al sucessivo,non necessita di parentesi,data la priorità degli operatori.
    Ricordo anche che i parametri di una funzione creano già di per sè una nuova variabile,in questo caso un puntatore a char,essendo quindi una nuova variabile non modifica in nessun modo il puntatore originario.
    Ottanta caratteri perchè ottanta caratteri è la console di default di windows,l'ho ciamata simple proprio perchè è soggetta a buffer overflow,ma il mio voleva essere solo un indirizzamento e non una pappa pronta.
    Finisco dicendo che ovviamente il codice funziona.
Devi accedere o registrarti per scrivere nel forum
11 risposte