PDA

Visualizza la versione completa : [C] struct con funzione


vide91
19-08-2014, 13:20
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


#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);
}
}

oregon
19-08-2014, 14:36
Togli /n dalla scanf

scanf("%d",&N);

vide91
19-08-2014, 15:42
Grazie...risolto

Xaratroom
20-08-2014, 11:46
Se non ricordo male, sarebbe comunque conveniente rimuovere il carattere \n "dall'stdin", una volta effettuata la lettura. Il modo migliore è il seguente:

scanf("%d%*c", &N);

PS: è un piacere rivederti Oregon

MItaly
20-08-2014, 22:54
In realtà per "mangiare" il whitespace (newline incluso) dovrebbe bastare


scanf("%d ", &N);

(nota lo spazio dopo il %d)

Xaratroom
21-08-2014, 13:41
In realtà per "mangiare" il whitespace (newline incluso) dovrebbe bastare


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.

MItaly
21-08-2014, 23:49
Ho sempre usato la direttiva di conversione %*c per mangiare la robaccia lasciata nell'stdin.
E avevi ragione, perché ricordavo male :dhò: 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. :stordita:

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).

M.A.W. 1968
22-08-2014, 01:02
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 (http://www.ioprogrammo.it/index.php?topic=19530.msg78844#msg78844), 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.

Loading