Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    131

    [C] struct con funzione

    salve,
    sto cercando di scrivere questo codice utilizzando struct . Solo che nel momento che eseguo il programma e inserisco il numero degli studenti, devo inserire due volte l' input altrimenti il programma non continua l'esecuzione, e poi quando arrivo all'inserimento dell' "anno" salta e mi chiede direttamente il nome (inizia un nuovo ciclo).
    Dove sbaglio? .....grazie
    codice:
    #include <stdio.h>
     
    struct studente {
     char cognome[10];
     char nome[20];
     int anno;
     char tipo[1];
    };
    
    void leggi(int n , struct studente Vet[]);
    int main (void){
     
     int N;
     struct studente V[N]; 
     
     printf("Inserisci il numero degli  studenti\n ");
     scanf("%d\n",&N);
     leggi(N,V);
      
     return 0;
    } 
     
    void leggi(int y , struct studente Vet[]){
        int i;
        for(i=0;i<y;i++){
            printf("Inserisci nome\n");
            scanf("%s\n",&Vet[i].nome);  
      printf("Inserisci Cognome\n");
            scanf("%s\n",&Vet[i].cognome);
            printf("Inserisci tipo abbonamento A annuale M mensile\n");
            scanf("%s\n",&Vet[i].tipo);  
      printf("Inserisci anno\n");
            scanf("%d\n",&Vet[i].anno);
      }
    }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Togli /n dalla scanf

    scanf("%d",&N);
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jul 2011
    Messaggi
    131
    Grazie...risolto

  4. #4
    Se non ricordo male, sarebbe comunque conveniente rimuovere il carattere \n "dall'stdin", una volta effettuata la lettura. Il modo migliore è il seguente:
    codice:
    scanf("%d%*c", &N);
    PS: è un piacere rivederti Oregon
    Experience is what you get when you don’t get what you want

  5. #5
    In realtà per "mangiare" il whitespace (newline incluso) dovrebbe bastare
    codice:
    scanf("%d ", &N);
    (nota lo spazio dopo il %d)
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    In realtà per "mangiare" il whitespace (newline incluso) dovrebbe bastare
    codice:
    scanf("%d ", &N);
    (nota lo spazio dopo il %d)
    Buono a sapersi. Ignoravo completamente il significato dei whitespace al termine della stringa di formattazione della scanf.
    Ho sempre usato la direttiva di conversione %*c per mangiare la robaccia lasciata nell'stdin.
    Experience is what you get when you don’t get what you want

  7. #7
    Quote Originariamente inviata da Xaratroom Visualizza il messaggio
    Ho sempre usato la direttiva di conversione %*c per mangiare la robaccia lasciata nell'stdin.
    E avevi ragione, perché ricordavo male il whitespace a fine scanf non funziona, perché la scanf continua ad aspettare a ritornare finché riceve whitespace, per cui non ritorna finché non vengono inseriti caratteri non-whitespace. Chiedo scusa per la confusione.

    Rileggendo le manpage della scanf, comunque, salta fuori che il "pulire" lo stream di input dovrebbe servire solo se dopo fai a fare una scanf con %c o con %[...] (o fai un'operazione di input non formattato, come fgets o fread), visto che, con l'eccezione degli specificatori in questione, il whitespace rimasto viene automaticamente scartato prima di iniziare a fare il parsing di quanto specificato nella stringa di formato (è come se nella stringa di formato ci fosse sempre uno spazio iniziale).
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Il sottosistema di regex nella stringa di formato della scanf() è notoriamente fallato ed arbitrario. Inoltre credo sia sempre il caso di rammentare ai newbie che tale funzione è pesantamente deprecata, in particolare proprio per l'input di stringhe.
    Come ammesso esplicitamente più volte dagli autori del linguaggio, e come ribadito dagli estensiori dei principali manuali di stile, scanf() e consimili sono null'altro che placeholders, buoni al più per prototipi a perdere o per uso didattico spiccio. Ci si attende infatti, nell'ordine, che il programmatore (anche aspirante):

    1) Si ingegni con altre funzioni di libreria, limitandosi a quelle standard se e solo se la genericità del corso lo esige;

    2) Prenda quanto prima confidenza con le fuzioni di I/O specifiche della piattaforma e del sistema operativo, ivi incluse quelle fornite di default dai compilatori nativi (es. la benemerita conio.h di Borland);

    3) Scriva quanto prima le proprie funzioni di I/O robuste e adatte alla bisogna, richiamando direttamente le API/syscall o usando adeguati wrapper;

    4) Ricorra a librerie o framework di terze parti, trovando di fatto già pronto - in una maggioranza di casi - quanto illustrato al punto precedente.

    Contrariamente alla schiacciante maggioranza dei linguaggi di alto livello, che forniscono "right out of the box" migliaia di funzioni anche avanzate (es. grafica), in linguaggio C anche la più elementare interazione con l'utente è affidata sostanzialmente a quanto sopra, a causa della natura prettamente portabile e multipiattaforma del linguaggio e delle sue implementazioni, le quali coprono senza soluzione di continuità l'uso su uno spettro di piattaforme che va dal mostruoso supercomputer IBM Z10 all'ultimo dei cross compiler C per un microcontroller a 8 bit con 64 byte di RAM e 4kib (o meno...) di program memory, passando per PC industriali, device mobile, e ovviamente i banali PC wintel.
    Ultima modifica di M.A.W. 1968; 22-08-2014 a 01:04
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

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.