rambo12345 Δημοσ. 16 Δεκεμβρίου 2015 Δημοσ. 16 Δεκεμβρίου 2015 Κάνω επανάληψη μία εργαστηριακή άσκηση με εκφώνηση: Γράψτε ένα πρόγραμμα σε C στο οποίο αρχικά θα δηλώνετε μια δομή για την περιγραφή ενός μαθητή. Συγκεκριμένα θεωρείστε ότι ο μαθητής περιγράφεται από το όνομά του και το μέσο όρο των βαθμών του. Στη συνέχεια το πρόγραμμά σας θα πρέπει να ζητάει από το χρήστη τον αριθμό των δομών για τις οποίες θα εισάγει δεδομένα και χρησιμοποιώντας τη συνάρτηση malloc() δεσμεύει τον απαραίτητο χώρο στη μνήμη. Ακολούθως, το πρόγραμμά σας θα ζητάει από το χρήστη τα στοιχεία της κάθε δομής και θα τα εισάγει στο χώρο που έχει δεσμεύσει. Μετά το τέλος της εισαγωγής στοιχείων το πρόγραμμα μας θα εκτυπώνει στην οθόνη τα στοιχεία του κάθε μαθητή που έχετε εισάγει, θα απελευθερώνει τη μνήμη που έχει δεσμεύσει και θα τελειώνει. Στο πρόγραμμά θα πρέπει να φροντίσετε να υπάρχουν, πέραν της συνάρτησης main(), τουλάχιστον τρεις συναρτήσεις: • συνάρτηση για την εισαγωγή των στοιχείων των δομών • συνάρτηση η οποία θα εκτυπώσει στην οθόνη τα στοιχεία των δομών • συνάρτηση για την απελευθέρωση της μνήμης την οποία δεσμεύσατε. και έχω γράψει τον παρακάτω κώδικα: #include <stdio.h> #include <stdlib.h> #include <string.h> struct students { char *name; float avg; }; void insert (struct students *table, int num); void print (struct students *table, int num); void free_memory (struct students *table, int num); main() { int num; struct students *table; printf ("Give Number Of Students\n"); scanf ("%d", &num); table=malloc(num*sizeof(struct students)); insert (table, num); print (table, num); free_memory(table, num); return 0; } void insert (struct students *table, int num) { int i,j; char temp[30]; for (i=0; i<num; i++) { printf ("Give name of student %d \n", i+1); j=0; scanf ("%c", &temp[j]); while (temp[j]!='\n') scanf ("%c", &temp[++j]); temp[j]='\0'; table.name=malloc(j*sizeof(char)); strcpy(table.name,temp); printf ("Give Average of student %d", i+1); scanf ("%f", &(table.avg)); while ((table.avg<0)||(table.avg>10)) { printf ("\nGive Average Again\n"); scanf ("%d", &(table.avg)); } } } void print (struct students *table, int num) { int i; for (i=0; i<num; i++) { printf ("\nName of Student %d", i+1); puts(table.name); printf ("\nAverage of Student %d", i+1); printf ("\n"); printf ("%0.1f", table.avg); printf ("\n\n\n"); } } void free_memory(struct students *table, int num) { free (table); } Στη συνάρτηση insert για κάποιο απροσδιόριστο λόγο δεν μου εκτελεί τις εντολές: j=0; scanf ("%c", &temp[j]); while (temp[j]!='\n') scanf ("%c", &temp[++j]); temp[j]='\0'; table.name=malloc(j*sizeof(char)); strcpy(table.name,temp); πραγματικά σαν να μην υπάρχουν! Τρέξτε το και θα δείτε..Μπορείτε να μου πείτε τι φταίει;
gon1332 Δημοσ. 16 Δεκεμβρίου 2015 Δημοσ. 16 Δεκεμβρίου 2015 Έχετε μάθει να διαβάζετε strings με scanf; Γιατί έτσι: j=0; scanf ("%c", &temp[j]); while (temp[j]!='\n') scanf ("%c", &temp[++j]); temp[j]='\0'; δε διαβάζεις string. To newline που πληκτρολογείς με το εξωτερικό scanf μένει και αποθηκεύεται στο δεύτερο. Δοκίμασε να δώσεις το όνομα ολόκληρο χωρίς κενά για να δεις τη συμπεριφορά.
DDevil Δημοσ. 16 Δεκεμβρίου 2015 Δημοσ. 16 Δεκεμβρίου 2015 Με την scanf μεσα στη λουπα της φορ διαβάζεις εναν χαρακτήρα και μετά με την λούπα του while διατρέχεις το στρινγκ μέχρι να βρεις τον χαρακτήρα αλλαγής γραμμής δηλαδη δεν έχει νοημα αυτη η ροή. Οι εντολές εκτελούνται κανονικά για 0<num που δινει αληθές μέσα στο βροχο υπάρχει ένας βροχος while ο οποιος διατρέχει το string μέχρι να βρει χαρακτήρα αλλαγής γραμμής. Σου προτεινω να χρησιμοποιήσεις την συνάρτηση fgets για το διάβασμα μιας συμβολοσειράς και να ξεχάσεις την scanf η συνάρτηση που σου λέω αν ο χρήστης πληκτρολογήσει μια συμβολοσειρά μεγαλυτερου μήκους απο αυτην που κανονικά χωράει στην μεταβλητή τοποθετεί εγγυημένα τον '\0' στο τελευταιο στοιχείο του πινακα.
gon1332 Δημοσ. 16 Δεκεμβρίου 2015 Δημοσ. 16 Δεκεμβρίου 2015 Με την scanf μεσα στη λουπα της φορ διαβάζεις εναν χαρακτήρα και μετά με την λούπα του while διατρέχεις το στρινγκ μέχρι να βρεις τον χαρακτήρα αλλαγής γραμμής δηλαδη δεν έχει νοημα αυτη η ροή. Οι εντολές εκτελούνται κανονικά για 0<num που δινει αληθές μέσα στο βροχο υπάρχει ένας βροχος while ο οποιος διατρέχει το string μέχρι να βρει χαρακτήρα αλλαγής γραμμής. Σου προτεινω να χρησιμοποιήσεις την συνάρτηση fgets για το διάβασμα μιας συμβολοσειράς και να ξεχάσεις την scanf η συνάρτηση που σου λέω αν ο χρήστης πληκτρολογήσει μια συμβολοσειρά μεγαλυτερου μήκους απο αυτην που κανονικά χωράει στην μεταβλητή τοποθετεί εγγυημένα τον '\0' στο τελευταιο στοιχείο του πινακα. Πρέπει όμως να προσέξει για την περίπτωση που θα ο χρήστης θα δώσει μικρότερο μέγεθος συμβολοσειράς να αφαιρέσει το newline. Μπορείς κάλλιστα να χρησιμοποιήσεις τη scanf, αλλά με %29s, format identifier. Όσον αφορά τον τρόπο που πήγε να διαβάσει το string, χαρακτήρα-χαρακτήρα δηλαδή, η λογική είναι σωστή, αλλά θέλει μεγαλύτερη προσοχή (δεν πετάει τους πλεονάζοντες white-space χαρακτήρες). Όπως και να έχει χρησιμοποιήσε σωστά τη scanf ή κάνε χρήση της fgets. Η δεύτερη προτιμάται καθώς είναι πιο ασφαλής, εφόσον δε δίνει περιθώρια λάθους απροσεξίας στον προγραμματιστή (να ξεχάσει να βάλει μέγεθος συμβολοσειράς στη scanf). 1
DDevil Δημοσ. 16 Δεκεμβρίου 2015 Δημοσ. 16 Δεκεμβρίου 2015 Ναι βάζει και τον newline μέσα απλα τον '\0' θα τον βάλει σε κάθε περιπτωση ακομα και αν χρειαστει να κοψει τη συμβολοσειρά απο ενα σημειο και μέτα αμα δεν φτάνει ο χώρος.Εχει ωραια λογική σαν συνάρτηση. Μπορει και με getchar() πάντως και με scanf οπως ειπες.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα