[C] Problema con fgets()
Ciao a tutti ragazzi,
sto avendo un problema nell'implementazione di una funzione che mi salvi i dati in un array di struct. Quando mando in esecuzione il codice, la prima volta, funziona alla perfezione, quando però dopo il controllo scelgo di inserire un altro cantiere il programma mi "salta" l'inserimento del nome. Per fare un esempio, mi stampa:
"Inserisci nome:
Inserisci cognome:"
Senza darmi la possibilità di scrivere il nome. Come mai? Cosa sbaglio?
Scusate se il codice è un po' un casino ma sono alle prime armi.
sto avendo un problema nell'implementazione di una funzione che mi salvi i dati in un array di struct. Quando mando in esecuzione il codice, la prima volta, funziona alla perfezione, quando però dopo il controllo scelgo di inserire un altro cantiere il programma mi "salta" l'inserimento del nome. Per fare un esempio, mi stampa:
"Inserisci nome:
Inserisci cognome:"
Senza darmi la possibilità di scrivere il nome. Come mai? Cosa sbaglio?
Scusate se il codice è un po' un casino ma sono alle prime armi.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 50 //definisco struttura Info typedef struct{ char Nome[SIZE]; char Cognome[SIZE]; char Indirizzo[SIZE]; unsigned int nOperai; unsigned int AnnoA; unsigned int AnnoC; }Info;//fine stuttura void caricadati (Info array[SIZE], int i); void main (){ Info cantiere [SIZE]; int i=0; caricadati (cantiere, i); } void caricadati (Info array[SIZE], int i) { char rip [3] = {0}; puts("Inserisci nome:"); fgets(array[i].Nome,SIZE,stdin); printf("Inserisci cognome: \n"); fgets(array[i].Cognome,SIZE,stdin); printf("Inserisci indirizzo: \n"); fgets(array[i].Indirizzo,SIZE,stdin); printf ("Inserisci il numero di Operai del Cantiere\n"); scanf ("%d", &array[i].nOperai); printf ("Inserisci l'anno di apertura del Cantiere\n"); scanf ("%d", &array[i].AnnoA); printf ("Inserisci l'anno di chiusura del Cantiere\n"); scanf ("%d", &array[i].AnnoC); printf ("Vuoi inseriri i dati di un'altro cantiere o tornare al menu?\n"); printf ("SI per inserire un nuovo cantiere NO per tornare al menu\n"); scanf ("%c%c", &rip[0], &rip[1]); if (rip[1]=='S' || rip[1]=='S') { caricadati (array, i+1); } else if (rip[1]=='N' || rip[1]=='n') { return; } else if (rip[1]!='N' && rip[1]!='n' && rip[1]!='S' && rip[1]!='s') { system ("cls"); printf("\t-----------------\n"); printf("\t---- ERRORE! ----\n"); printf("\t-----------------\n"); printf("\a\tScelta inesistente! \n"); system ("PAUSE"); system ("cls"); return main(); } }
Risposte
Ma se usi un banale scanf per memorizzare?
per esempio:
printf("Inserisci nome:");
scanf("%s", array.Nome);
per esempio:
printf("Inserisci nome:");
scanf("%s", array.Nome);
Non memorizzerebbe gli spazi, se dovessi inserire per esempio un cognome tipo "Di Girolamo" o una via come "Giuseppe Garibaldi".
Non la leggerebbe tutta ma, all'inserimento dello spazio si interromperebbe la scanf
Non la leggerebbe tutta ma, all'inserimento dello spazio si interromperebbe la scanf
Prima di tutto a me non compila neanche senza fare diverse modifiche. Che compilatore stai usando?
Il problema non ha poi nulla a che fare con fgets, ma con scanf.. Il seguente codice legge due caratteri e poi mantiene nel buffer di lettura il carattere di a capo inserito necessariamente dopo tali caratteri. Quando fgets viene chiamato c'è quindi ancora parte della riga precedente nel buffer di lettura e restituisce quello.
@m4551: Quella banale riga di codice è un esempio di come NON leggere una stringa da stdin. Puoi piuttosto usare qualcosa come
ma credo che l'uso di fgets sia dovuto al desiderio di leggere anche stringhe contenenti spazi. Una persona può avere nomi o cognomi formati da più parole.
Il problema non ha poi nulla a che fare con fgets, ma con scanf.. Il seguente codice legge due caratteri e poi mantiene nel buffer di lettura il carattere di a capo inserito necessariamente dopo tali caratteri. Quando fgets viene chiamato c'è quindi ancora parte della riga precedente nel buffer di lettura e restituisce quello.
printf ("SI per inserire un nuovo cantiere NO per tornare al menu\n"); scanf ("%c%c", &rip[0], &rip[1]);
@m4551: Quella banale riga di codice è un esempio di come NON leggere una stringa da stdin. Puoi piuttosto usare qualcosa come
scanf("%49s", array[i].Node);
ma credo che l'uso di fgets sia dovuto al desiderio di leggere anche stringhe contenenti spazi. Una persona può avere nomi o cognomi formati da più parole.
Sto usando Dev C++ 5.8.3 (credo tu intenda questo).
Quindi come mi consiglieresti di sostituire quella riga? ho provato con "fgets" anche lì ma poi nel controllo crasha. Tra l'altro ho notato che la ricorsione così non la posso usare, il che aggiunge un altro problema(che posso risolvere con un ciclo for o un while quindi non è un problema, era solo per avere un codice migliore).
Quindi come mi consiglieresti di sostituire quella riga? ho provato con "fgets" anche lì ma poi nel controllo crasha. Tra l'altro ho notato che la ricorsione così non la posso usare, il che aggiunge un altro problema(che posso risolvere con un ciclo for o un while quindi non è un problema, era solo per avere un codice migliore).