matheostsik Δημοσ. 18 Ιανουαρίου 2018 Δημοσ. 18 Ιανουαρίου 2018 (επεξεργασμένο) Καλησπερα γραφω ενα προγραμμα που θα πρεπει να εκτελει 5 λειτουργιες (οχι ταυτοχρονα) αναλογα με το τι θα δοθει στα command line arguments. Για παραδειγμα --insert: (δημιουργει και) εισαγει δεδομενα σε μια απλα συνδεδεμενη λιστα που περιεχει 2 int,1 string και 1 float. Αλλες λειτουργιες :--reset,--delete,--list-all,--list-after Το θεμα μου ειναι οτι ολα αυτα πρεπει να αποθηκευονται σε ενα αρχειο τυπου .dat και να διαβαζονται επισης απο εκει. Μεχρι στιγμης εχω γραψει ενα προγραμμα που εκτελει ολες τις λειτουργιες με συναρτησεις αλλα χωρις να εχω συνδεσει καπως το αρχειο.Πως μπορω να αποθηκευσω ολοκληρη τη δομη στο αρχειο και αφου κλεισει το προγραμμα ,οταν ξανανοιξει να την ξαναφορτωνει? Ευχαριστω. Επεξ/σία 18 Ιανουαρίου 2018 από matheostsik
kaliakman Δημοσ. 18 Ιανουαρίου 2018 Δημοσ. 18 Ιανουαρίου 2018 21 λεπτά πριν, matheostsik είπε Καλησπερα γραφω ενα προγραμμα που θα πρεπει να εκτελει 5 λειτουργιες (οχι ταυτοχρονα) αναλογα με το τι θα δοθει στα command line arguments. Για παραδειγμα --insert: (δημιουργει και) εισαγει δεδομενα σε μια απλα συνδεδεμενη λιστα που περιεχει 2 int,1 string και 1 float. Αλλες λειτουργιες :--reset,--delete,--list-all,--list-after Το θεμα μου ειναι οτι ολα αυτα πρεπει να αποθηκευονται σε ενα αρχειο τυπου .dat και να διαβαζονται επισης απο εκει. Μεχρι στιγμης εχω γραψει ενα προγραμμα που εκτελει ολες τις λειτουργιες με συναρτησεις αλλα χωρις να εχω συνδεσει καπως το αρχειο.Πως μπορω να αποθηκευσω ολοκληρη τη δομη στο αρχειο και αφου κλεισει το προγραμμα ,οταν ξανανοιξει να την ξαναφορτωνει? Ευχαριστω. Πρέπει να αποφασίσεις πως θα την έχεις την πληροφορία μέσα στο αρχείο. Για παράδειγμα μπορείς ανα γραμμή να έχεις έναν κόμβο και τα πεδία του να χωρίζονται με κόμμα. Κάθε φορά που ξεκινάει το πρόγραμμα φορτώνεις όλο το αρχείο κάνοντας parse την μορφή που ήδη ξέρεις και στο τέλος πάλι το διαγράφεις/γράφεις κατάλληλα! 1
imitheos Δημοσ. 18 Ιανουαρίου 2018 Δημοσ. 18 Ιανουαρίου 2018 (επεξεργασμένο) Ο πιο εύκολος τρόπος και αυτός που θα δεις συνήθως σε ασκήσεις (υποθέτω ότι πρόκειται για άσκηση) είναι να γράφεις ολόκληρη τη δομή με fwrite και sizeof. Έπειτα την διαβάζεις πάλι ολόκληρη με fread. Δεν είναι όμως δόκιμος τρόπος γιατί η δομή θα αποθηκευτεί όπως ακριβώς βρίσκεται στην μνήμη. Έτσι αν εσύ σώσεις ένα integer από x86 που είναι little-endian και αυτός που θα διαβάσει το αρχείο το κάνει από big-endian θα διαβάσει άλλο αριθμό. Εκτός από αυτό που δεν είναι και τόσο πιθανό σενάριο, υπάρχουν και άλλα προβλήματα όπως πχ πόσο padding θα υπάρχει ανάμεσα στα στοιχεία της δομής, το οποίο μπορεί να αλλάζει από compiler σε compiler και στην ίδια αρχιτεκτονική ακόμη (ή και στον ίδιο compiler με άλλες παραμέτρους). Αν εσύ ορίζεις τι μορφή θα έχουν τα δεδομένα στο αρχείο, τότε είναι εύκολο και απλά πρέπει να σκεφτείς πώς θέλεις να τα αποθηκεύεις. Μπορείς να βρεις πάρα πολλές πληροφορίες στο θέμα αν ψάξεις c struct serialization. Για παράδειγμα θα μπορούσες να αποθηκεύεις και τους αριθμούς ως strings και κάθε πεδίο να χωρίζεται με κόμμα από το προηγούμενο (όπως είναι δηλαδή τα csv αρχεία). Επεξ/σία 18 Ιανουαρίου 2018 από imitheos 2
matheostsik Δημοσ. 18 Ιανουαρίου 2018 Μέλος Δημοσ. 18 Ιανουαρίου 2018 25 λεπτά πριν, kaliakman είπε Πρέπει να αποφασίσεις πως θα την έχεις την πληροφορία μέσα στο αρχείο. Για παράδειγμα μπορείς ανα γραμμή να έχεις έναν κόμβο και τα πεδία του να χωρίζονται με κόμμα. Κάθε φορά που ξεκινάει το πρόγραμμα φορτώνεις όλο το αρχείο κάνοντας parse την μορφή που ήδη ξέρεις και στο τέλος πάλι το διαγράφεις/γράφεις κατάλληλα! Ανα γραμμη θελω να ειναι ο καθε κομβος και η καθε πληροφορια να χωριζεται μεταξυ με κενο
kaliakman Δημοσ. 18 Ιανουαρίου 2018 Δημοσ. 18 Ιανουαρίου 2018 2 λεπτά πριν, matheostsik είπε Ανα γραμμη θελω να ειναι ο καθε κομβος και η καθε πληροφορια να χωριζεται μεταξυ με κενο Για το πως να γράψεις δες εδώ είναι trivial: https://stackoverflow.com/questions/11573974/write-to-txt-file προφανώς στην fopen θα βάλεις το κατάλληλο όνομα/extension αλλά γενικότερα είναι σαν να printάρεις με printf. To διάβασμα είναι λίγο πιο πολύπλοκο επείδη δεν έχεις τρόπο στην c να πάρεις input μέχρι να βρείς έναν delimiter (εδώ το κενό) αναγκαστικά θα πάρεις όλη την γραμμή και θα την parseάρεις μόνος σου(να ψάξεις μέχρι να βρεις το κάθε κενό και μετά να κάνεις κατάλληλα strcpy για να τα περάσεις στην δομή σου): https://stackoverflow.com/questions/3463426/in-c-how-should-i-read-a-text-file-and-print-all-strings
matheostsik Δημοσ. 22 Ιανουαρίου 2018 Μέλος Δημοσ. 22 Ιανουαρίου 2018 Καλησπερα,Αρχικα ναι για ασκηση προκειται αλλα τελικα πρεπει να γινει με διαφορετικο τροπο απο οτι εξηγω παραπανω. Πρεπει να ανοιξω το αρχειο να διαβασω τις εγγραφες που εχει μεσα να τις εισαγω σε λιστα και μετα να εκτελω μια απο τις 5 επιλογες,στο τελος να αποθηκευω τη λιστα στο αρχειο. ο κωδικας που εχω θεμα ειναι αυτος //... fp=fopen("movies.dat","rb"); while(1){ /*Anoigma arxeiou + dhmiourgia listas*/ fread(&len,sizeof(int),1,fp); name=malloc(len*sizeof(char)); fread(name,len*sizeof(char),1,fp); fread(&year,sizeof(int),1,fp); fread(&funds,sizeof(float),1,fp); if(start==NULL){ start = addatbeg(start,len,name,year,funds); }else{ addatend(start,len,name,year,funds);} free(name); if( feof(fp) ) { break ;} } fclose(fp); display(start); //... void display(struct node *start){ struct node *p; if(start==NULL){ printf("\nList is empty\n"); return; } p=start; printf("\nList is : \n"); while(p != NULL){ printf("%s %d %.2f \n", p->name,p->year,p->funds); p=p->link; } }
kaliakman Δημοσ. 22 Ιανουαρίου 2018 Δημοσ. 22 Ιανουαρίου 2018 (επεξεργασμένο) Το πρόβλημα ποιο είναι? Ότι εμφανίζεται αυτή η γραμμή και άλλη φορα χωρίς όνομα? Είναι αυτή η τελευταία εγγραφή στο αρχείο? Επίσης όταν κάνεις malloc για ένα string με len size στην ουσία έχεις διαθέσιμο len -1 χώρο γιατί υπάρχει και το \0 στο τέλος οπότε ίσως να θες να κάνεις malloc len+1 Επεξ/σία 22 Ιανουαρίου 2018 από kaliakman 1
matheostsik Δημοσ. 22 Ιανουαρίου 2018 Μέλος Δημοσ. 22 Ιανουαρίου 2018 2 λεπτά πριν, kaliakman είπε Το πρόβλημα ποιο είναι? Ότι εμφανίζεται αυτή η γραμμή και άλλη φορα χωρίς όνομα? Είναι αυτή η τελευταία εγγραφή στο αρχείο? Το προβλημα ειναι οτι "ξαναfreadarei" ενω το αρχειο τελειωνει στην δευτερη γραμμη.(η καθε γραμμη κανονικα περιεχει: int(που δεν εμφανιζεται) ,string, int,float.
kaliakman Δημοσ. 22 Ιανουαρίου 2018 Δημοσ. 22 Ιανουαρίου 2018 Βάλε τον κώδικα που γράφει το αρχείο στο τέλος καθώς και τον κώδικα για το add στην λίστα. Σε ένα από τα δυο λογικά υπάρχει πρόβλημα. 1
matheostsik Δημοσ. 22 Ιανουαρίου 2018 Μέλος Δημοσ. 22 Ιανουαρίου 2018 1 λεπτό πριν, kaliakman είπε Βάλε τον κώδικα που γράφει το αρχείο στο τέλος καθώς και τον κώδικα για το add στην λίστα. Σε ένα από τα δυο λογικά υπάρχει πρόβλημα. struct node *addatbeg(struct node *start,int len,char *name,int year,float funds){ struct node *temp; temp=(struct node *)malloc(sizeof(struct node)); temp->year=year; strcpy(temp->name,name); temp->len=len; temp->funds=funds; temp->link = start; start = temp; return start;} void addatend(struct node *start,int len,char *name,int year,float funds){ struct node *temp, *p; temp=(struct node *)malloc(sizeof(struct node)); temp->year=year; strcpy(temp->name,name); temp->len=len; temp->funds=funds; p=start; while(p->link!=NULL){ p = p->link; } p->link = temp; temp->link = NULL;}
kaliakman Δημοσ. 22 Ιανουαρίου 2018 Δημοσ. 22 Ιανουαρίου 2018 (επεξεργασμένο) Στην addatbeg γιατί γράφεις? temp->link = start; start = temp; αφού το start είναι πάντα NULL δεν μπορείς να γράψεις απευθείας: temp->link = NULL; start = temp; Αν το κάνεις αυτό μήπως βλέπεις ομοιότητες με την addatend? Τελικά χρειάζεσαι δύο συναρτήσεις για το add?? Επεξ/σία 22 Ιανουαρίου 2018 από kaliakman
matheostsik Δημοσ. 22 Ιανουαρίου 2018 Μέλος Δημοσ. 22 Ιανουαρίου 2018 (επεξεργασμένο) 11 λεπτά πριν, kaliakman είπε Στην addatbeg γιατί γράφεις? temp->link = start; start = temp; αφού το start είναι πάντα NULL δεν μπορείς να γράψεις απευθείας: temp->link = NULL; start = temp; Αν το κάνεις αυτό μήπως βλέπεις ομοιότητες με την addatend? Τελικά χρειάζεσαι δύο συναρτήσεις για το add?? Την addatbeg την έβαλα περισσοτερο για να δημιουργείται ο πρώτος βρόχος.Δηλαδη προτείνεις να ψιλοαλλαξω την addatbeg και να κρατήσω μόνο αυτή; Επεξ/σία 22 Ιανουαρίου 2018 από matheostsik
kaliakman Δημοσ. 22 Ιανουαρίου 2018 Δημοσ. 22 Ιανουαρίου 2018 1 λεπτό πριν, matheostsik είπε Την addatbeg την έβαλα περισσοτερο για να δημιουργείται ο πρώτος βρόχος.Δηλαδη προτείνεις να ψιλοαλλαξω την addatbeg και να κρατήσω μόνο αυτή; Όχι προτείνω να σβήσεις τελείως την addatbeg. Μήπως με μικρή αλλάγη στην addatend έχεις το ίδιο αποτέλεσμα με μια όμως συνάρτηση; Τα οφέλη για αυτό είναι πολλά. Έχεις ένα σημείο που μπορεί να γίνεται λάθος,όταν θες να κάνεις μια αλλάγη την κάνεις σε ένα μόνο σημείο κτλ. Βάλε και τον κώδικα που γράφει στο αρχείο για να δούμε για το πρόβλημα που ανέφερες.
matheostsik Δημοσ. 22 Ιανουαρίου 2018 Μέλος Δημοσ. 22 Ιανουαρίου 2018 19 λεπτά πριν, kaliakman είπε Όχι προτείνω να σβήσεις τελείως την addatbeg. Μήπως με μικρή αλλάγη στην addatend έχεις το ίδιο αποτέλεσμα με μια όμως συνάρτηση; Τα οφέλη για αυτό είναι πολλά. Έχεις ένα σημείο που μπορεί να γίνεται λάθος,όταν θες να κάνεις μια αλλάγη την κάνεις σε ένα μόνο σημείο κτλ. Βάλε και τον κώδικα που γράφει στο αρχείο για να δούμε για το πρόβλημα που ανέφερες. Τον εχω πολυ προχειρα ισα για να καταλαβω πως λειτουργει η fwrite επειδη δεν προλαβα να φτασω μεχρι εκει λογω το παραπανω προβληματος.
kaliakman Δημοσ. 22 Ιανουαρίου 2018 Δημοσ. 22 Ιανουαρίου 2018 Μόλις τώρα, matheostsik είπε Τον εχω πολυ προχειρα ισα για να καταλαβω πως λειτουργει η fwrite επειδη δεν προλαβα να φτασω μεχρι εκει λογω το παραπανω προβληματος. Μήπως εδώ είναι το πρόβλημα σου? Όταν φτιάχνεις το αρχείο το έχεις ανοίξει να το δεις; Είναι καλά γραμμένο; Δηλαδή η τελευταία γραμμή είναι όντως αυτό που θες;
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα