Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    13

    [C] Lettura dati immessi dall'utente

    Salve a tutti,
    sono un nuovo utente appena registrato

    Vi volevo porre un quesito..Sto provando a scrivere un programma in C (è un esercizio del mio parziale all'uni) e ho un problema nel registrare in sequenza i dati immessi dall'utente..Mi spiego..

    Il codice è questo:

    codice:
    #include <stdio.h>
    
    int Prodotti;
    
    int optionals(int n, char op[][7]);
    int optional_s(int n, int p, char op[][7]);
    
    int main(void)
    {
        printf("Inserisci il numero di prodotti\n");
        scanf("%d",&Prodotti);
    
        double alt_larg[Prodotti][2];
        int colore[Prodotti];
        char optional[Prodotti][7];
        int crit_a=0, crit_b=0, crit_c=0, t1_crit_c, t2_crit_c, i = 0, j, bassi=0, aster=0;
    
        for(; i < Prodotti; i++)
        {
            printf("Inserisci le caratteristiche dell oggetto\n"); /*QUI!!*/ 
            scanf("%lf %lf %d %s", &alt_larg[i][0], &alt_larg[i][1], &colore[i], &optional[i]);
            printf("\n");
        }
    
        i=0;
    
        for (; i < Prodotti; i++)
        {
            t1_crit_c=0;
            t2_crit_c=0;
            j=0;
            if ((optionals(i,optional) <= 2) || ((colore[i] == 2) && ((optionals(i,optional) >= 2) || (optional_s(4,i,optional)))))
                break;
    
            for(; j < Prodotti; j++)
            {
                if ((alt_larg[j][0] < alt_larg[i][0]) && (optionals(j,optional) >= 2))
                    bassi++;
    
                if (alt_larg[j][0] < alt_larg[i][0])
                    t1_crit_c++;
    
                if (alt_larg[j][1] > alt_larg[i][1])
                    t2_crit_c++;
            }
    
            if (bassi >= 3) {aster=1; continue;}
    
            if ((t1_crit_c <= 2) && (t2_crit_c >= 3))
                crit_c++;
    
            if ((optionals(i,optional) >= 3) && ((colore[i] == 3) || (colore[i] == 5)))
                crit_a++;
    
            if (((alt_larg[i][0] < alt_larg[i][1]) && (optional_s(2,i,optional))) || ((optionals(i,optional) <= 2) && (colore[i] == 2)))
                crit_b++;
        }
    
        if ((crit_a <= 4) || (crit_b <= 4) || (crit_c <= 4))
            printf("OK");
        else
            printf("KO");
    
        if (aster==1)
            printf("***");
    }
    
    int optionals(int n, char op[][7])
    {
        int i = 0, j = 0;
        for(; i < 7; i++)
        {
            if(op[n][i] == 'y')
                j++;
        }
        return j;
    }
    
    int optional_s(int n, int p, char op[][7])
    {
        int k, j;
        k = n == 1 ? 1 : (2*n)-1;
        j = op[p][k] == 'y' ? 1 : 0;
        return j;
    }
    nel punto dove ho segnato con il commento in rosso c'è un loop che dovrebbe registrare le caratteristiche di ogni oggetto inserito, uno per volta..ma quando inserisco i dati del primo oggetto il loop non si ferma ad ogni singolo oggetto ma scorre e termina..perchè? ho fatto qualche errore?

    Ringrazio in anticipo ed attendo risposte esaustive a presto!

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Intendi dire che riesci a inserire solo i dati del primo oggetto e poi termina subito il ciclo di inserimento?

    Comunque tra le altre cose:

    - nella scanf() l'argomento &optional[i] non corrisponde come tipo al codice di formato relativo: %s si aspetta un puntatore a char, ma &optional[i] è di tipo "char (*)[7]"; devi togliere la &, optional[i] da solo è già l'indirizzo di base
    della stringa da inserire (tra l'altro fai attenzione a non inserire più di 6 caratteri altrimenti incorri in un buffer overflow visto che ogni stringa ha dimensione 7);
    - dichiarare array di qualsiasi dimensione a size variabile è una pratica sconsigliata per alcuni motivi, principalmente perché rientrante nello standard C99 che non è implementato da tutti i compilatori (o comunque non sempre completamente). Ricorri all'allocazione statica con size costante (magari utilizzando una #define) oppure all'allocazione dinamica se hai bisogno di creare array di dimensioni variabili.
    every day above ground is a good one

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    13
    si riesco ad inserire solo i dati per il primo oggetto...

    ok la & l'ho tolta ed ho aumentato ad 8 l'array dato che venivano inseriti 7 caratteri..Però il problema persiste..

    Ho anche aggiunto Static alla variabile Prodotti che serve per determinare la lunghezza degli array ma nulla..

    Cmq grazie per la risposta

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Originariamente inviato da laurgaor
    ok la & l'ho tolta ed ho aumentato ad 8 l'array dato che venivano inseriti 7 caratteri..Però il problema persiste..

    Ho anche aggiunto Static alla variabile Prodotti che serve per determinare la lunghezza degli array ma nulla..
    I suggerimenti che ti davo erano indipendenti dal problema, tra l'altro dichiarare "static" una variabile non significa renderla una costante... il punto è che nella definizione delle dimensioni di un array non dovrebbe mai esserci una variabile, ma solo costanti intere (10, 15, 145) o al massimo costanti simboliche definite con #define, sennò si ricorre all'allocazione dinamica con malloc() e calloc().

    Comunque a parte questo, sei sicuro di inserire i dati correttamente? Puoi anche provare a inserire ques'istruzione subito dopo la scanf()

    codice:
    while (getchar() != '\n');
    (nota il ; alla fine) dato che potrebbe essere un problema di caratteri di newline che rimangono nel buffer di input da tastiera e che ti fanno saltare le istruzioni di lettura successive.
    every day above ground is a good one

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    13
    si hai ragione mi sono imbrogliato..

    comunque con il while che mi hai scritto funziona..puoi spiegarmi un pò più dettagliatamente cosa cambia?

    grazie mille dell'aiuto

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Un irrisolto (=per vie standard) problema dell'input bufferizzato in C. Quando immetti caratteri da tastiera, questi vengono inizialmente salvati in un buffer (cioè una memoria "tampone") associato allo stream di input standard (stdin), che generalmente corrisponde appunto alla tastiera. I valori nel buffer vengono rilasciati e salvati nell'area di memoria indicata (cioè nella variabile di cui passi l'indirizzo alla scanf) nel momento in cui premi INVIO, che corrisponde generalmente al carattere di newline ('\n'). Il problema è che spesso questo newline non viene letto e scartato come dovrebbe essere, ma rimane nel buffer di input, quindi all'istruzione di input successiva ti ritrovi come se avessi premuto subito INVIO senza inserire dati, quindi di fatto la salti. Quel while serve appunto a leggere tutti i caratteri rimasti nel buffer fino al newline (incluso), che viene quindi esplicitamente rimosso (può servire anche nel caso in cui la scanf() fallisca ad esempio leggendo una stringa laddove si attenderebbe un intero).

    A volte basta anche un fflush(stdin) dopo la scanf che però è da evitare perché non è detto che funzioni con tutti i compilatori, infatti lo standard C non definisce un comportamento per la funzione fflush() richiamata su stream di input (quindi con alcuni compilatori ottieni l'effetto di ripulire il buffer, con altri non succede nulla, con altri ancora puoi avviare inconsapevolmente un processo di desertificazione - altamente improbabile, ma teoricamente possibile - e simili).
    every day above ground is a good one

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2011
    Messaggi
    13
    Originariamente inviato da YuYevon
    Un irrisolto (=per vie standard) problema dell'input bufferizzato in C. Quando immetti caratteri da tastiera, questi vengono inizialmente salvati in un buffer (cioè una memoria "tampone") associato allo stream di input standard (stdin), che generalmente corrisponde appunto alla tastiera. I valori nel buffer vengono rilasciati e salvati nell'area di memoria indicata (cioè nella variabile di cui passi l'indirizzo alla scanf) nel momento in cui premi INVIO, che corrisponde generalmente al carattere di newline ('\n'). Il problema è che spesso questo newline non viene letto e scartato come dovrebbe essere, ma rimane nel buffer di input, quindi all'istruzione di input successiva ti ritrovi come se avessi premuto subito INVIO senza inserire dati, quindi di fatto la salti. Quel while serve appunto a leggere tutti i caratteri rimasti nel buffer fino al newline (incluso), che viene quindi esplicitamente rimosso (può servire anche nel caso in cui la scanf() fallisca ad esempio leggendo una stringa laddove si attenderebbe un intero).

    A volte basta anche un fflush(stdin) dopo la scanf che però è da evitare perché non è detto che funzioni con tutti i compilatori, infatti lo standard C non definisce un comportamento per la funzione fflush() richiamata su stream di input (quindi con alcuni compilatori ottieni l'effetto di ripulire il buffer, con altri non succede nulla, con altri ancora puoi avviare inconsapevolmente un processo di desertificazione - altamente improbabile, ma teoricamente possibile - e simili).
    ah ho capito grazie mille per la spiegazione!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.