Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Καλησπερα γραφω ενα προγραμμα που θα πρεπει να εκτελει 5 λειτουργιες (οχι ταυτοχρονα) αναλογα με το τι θα δοθει στα command line arguments.

Για παραδειγμα --insert: (δημιουργει και) εισαγει δεδομενα σε μια απλα συνδεδεμενη λιστα που περιεχει 2 int,1 string και 1 float.

Αλλες λειτουργιες :--reset,--delete,--list-all,--list-after

Το θεμα μου ειναι οτι ολα αυτα πρεπει να αποθηκευονται σε ενα αρχειο τυπου .dat και να διαβαζονται επισης απο εκει.

Μεχρι στιγμης εχω γραψει ενα προγραμμα που εκτελει ολες τις λειτουργιες με συναρτησεις αλλα χωρις να εχω συνδεσει καπως το αρχειο.Πως μπορω να αποθηκευσω ολοκληρη τη δομη στο αρχειο και αφου κλεισει το προγραμμα ,οταν ξανανοιξει να την ξαναφορτωνει?

Ευχαριστω.

Επεξ/σία από matheostsik
Δημοσ.
21 λεπτά πριν, matheostsik είπε

Καλησπερα γραφω ενα προγραμμα που θα πρεπει να εκτελει 5 λειτουργιες (οχι ταυτοχρονα) αναλογα με το τι θα δοθει στα command line arguments.

Για παραδειγμα --insert: (δημιουργει και) εισαγει δεδομενα σε μια απλα συνδεδεμενη λιστα που περιεχει 2 int,1 string και 1 float.

Αλλες λειτουργιες :--reset,--delete,--list-all,--list-after

Το θεμα μου ειναι οτι ολα αυτα πρεπει να αποθηκευονται σε ενα αρχειο τυπου .dat και να διαβαζονται επισης απο εκει.

Μεχρι στιγμης εχω γραψει ενα προγραμμα που εκτελει ολες τις λειτουργιες με συναρτησεις αλλα χωρις να εχω συνδεσει καπως το αρχειο.Πως μπορω να αποθηκευσω ολοκληρη τη δομη στο αρχειο και αφου κλεισει το προγραμμα ,οταν ξανανοιξει να την ξαναφορτωνει?

Ευχαριστω.

Πρέπει να αποφασίσεις πως θα την έχεις την πληροφορία μέσα στο αρχείο.

Για παράδειγμα μπορείς ανα γραμμή να έχεις έναν κόμβο και τα πεδία του να χωρίζονται με κόμμα.

Κάθε φορά που ξεκινάει το πρόγραμμα φορτώνεις όλο το αρχείο κάνοντας parse την μορφή που ήδη ξέρεις και στο τέλος πάλι το διαγράφεις/γράφεις κατάλληλα!

  • Thanks 1
Δημοσ. (επεξεργασμένο)

Ο πιο εύκολος τρόπος και αυτός που θα δεις συνήθως σε ασκήσεις (υποθέτω ότι πρόκειται για άσκηση) είναι να γράφεις ολόκληρη τη δομή με fwrite και sizeof. Έπειτα την διαβάζεις πάλι ολόκληρη με fread.

Δεν είναι όμως δόκιμος τρόπος γιατί η δομή θα αποθηκευτεί όπως ακριβώς βρίσκεται στην μνήμη. Έτσι αν εσύ σώσεις ένα integer από x86 που είναι little-endian και αυτός που θα διαβάσει το αρχείο το κάνει από big-endian θα διαβάσει άλλο αριθμό. Εκτός από αυτό που δεν είναι και τόσο πιθανό σενάριο, υπάρχουν και άλλα προβλήματα όπως πχ πόσο padding θα υπάρχει ανάμεσα στα στοιχεία της δομής, το οποίο μπορεί να αλλάζει από compiler σε compiler και στην ίδια αρχιτεκτονική ακόμη (ή και στον ίδιο compiler με άλλες παραμέτρους).

Αν εσύ ορίζεις τι μορφή θα έχουν τα δεδομένα στο αρχείο, τότε είναι εύκολο και απλά πρέπει να σκεφτείς πώς θέλεις να τα αποθηκεύεις. Μπορείς να βρεις πάρα πολλές πληροφορίες στο θέμα αν ψάξεις c struct serialization. Για παράδειγμα θα μπορούσες να αποθηκεύεις και τους αριθμούς ως strings και κάθε πεδίο να χωρίζεται με κόμμα από το προηγούμενο (όπως είναι δηλαδή τα csv αρχεία).

Επεξ/σία από imitheos
  • Thanks 2
Δημοσ.
25 λεπτά πριν, kaliakman είπε

Πρέπει να αποφασίσεις πως θα την έχεις την πληροφορία μέσα στο αρχείο.

Για παράδειγμα μπορείς ανα γραμμή να έχεις έναν κόμβο και τα πεδία του να χωρίζονται με κόμμα.

Κάθε φορά που ξεκινάει το πρόγραμμα φορτώνεις όλο το αρχείο κάνοντας parse την μορφή που ήδη ξέρεις και στο τέλος πάλι το διαγράφεις/γράφεις κατάλληλα!

Ανα γραμμη θελω να ειναι ο καθε κομβος και η καθε πληροφορια να χωριζεται μεταξυ με κενο

Δημοσ.
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

Δημοσ.

Καλησπερα,Αρχικα ναι για ασκηση προκειται αλλα τελικα πρεπει να γινει με διαφορετικο τροπο απο οτι εξηγω παραπανω.

Πρεπει να ανοιξω το αρχειο να διαβασω τις εγγραφες που εχει μεσα να τις εισαγω σε λιστα και μετα να εκτελω μια απο τις 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;
     }
}

image.png.9e47de15d37783aa74af61eaa8f87874.png

Δημοσ. (επεξεργασμένο)

Το πρόβλημα ποιο είναι?

 

Ότι εμφανίζεται αυτή η γραμμή και άλλη φορα χωρίς όνομα? Είναι αυτή η τελευταία εγγραφή στο αρχείο?

 

Επίσης όταν κάνεις malloc για ένα string με len size στην ουσία έχεις διαθέσιμο len -1 χώρο γιατί υπάρχει και το \0 στο τέλος οπότε ίσως να θες να κάνεις malloc len+1

Επεξ/σία από kaliakman
  • Like 1
Δημοσ.
2 λεπτά πριν, kaliakman είπε

Το πρόβλημα ποιο είναι?

Ότι εμφανίζεται αυτή η γραμμή και άλλη φορα χωρίς όνομα? Είναι αυτή η τελευταία εγγραφή στο αρχείο?

Το προβλημα ειναι οτι "ξαναfreadarei" ενω το αρχειο τελειωνει στην δευτερη γραμμη.(η καθε γραμμη κανονικα περιεχει: int(που δεν εμφανιζεται) ,string, int,float.

Δημοσ.

Βάλε τον κώδικα που γράφει το αρχείο στο τέλος καθώς και τον κώδικα για το add στην λίστα. Σε ένα από τα δυο λογικά υπάρχει πρόβλημα.

  • Like 1
Δημοσ.
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;}

 

Δημοσ. (επεξεργασμένο)

Στην addatbeg γιατί γράφεις?

temp->link = start;
start = temp;

αφού το start είναι πάντα NULL δεν μπορείς να γράψεις απευθείας:

temp->link = NULL;
start = temp;

Αν το κάνεις αυτό μήπως βλέπεις ομοιότητες με την addatend? Τελικά χρειάζεσαι δύο συναρτήσεις για το add??

Επεξ/σία από kaliakman
Δημοσ. (επεξεργασμένο)
11 λεπτά πριν, kaliakman είπε

Στην addatbeg γιατί γράφεις?


temp->link = start;
start = temp;

αφού το start είναι πάντα NULL δεν μπορείς να γράψεις απευθείας:


temp->link = NULL;
start = temp;

Αν το κάνεις αυτό μήπως βλέπεις ομοιότητες με την addatend? Τελικά χρειάζεσαι δύο συναρτήσεις για το add??

Την addatbeg την έβαλα περισσοτερο για να δημιουργείται ο πρώτος βρόχος.Δηλαδη προτείνεις να ψιλοαλλαξω την addatbeg και να κρατήσω μόνο αυτή;

Επεξ/σία από matheostsik
Δημοσ.
1 λεπτό πριν, matheostsik είπε

Την addatbeg την έβαλα περισσοτερο για να δημιουργείται ο πρώτος βρόχος.Δηλαδη προτείνεις να ψιλοαλλαξω την addatbeg και να κρατήσω μόνο αυτή;

Όχι προτείνω να σβήσεις τελείως την addatbeg. Μήπως με μικρή αλλάγη στην addatend έχεις το ίδιο αποτέλεσμα με μια όμως συνάρτηση; Τα οφέλη για αυτό είναι πολλά. Έχεις ένα σημείο που μπορεί να γίνεται λάθος,όταν θες να κάνεις μια αλλάγη την κάνεις σε ένα μόνο σημείο κτλ.
Βάλε και τον κώδικα που γράφει στο αρχείο για να δούμε για το πρόβλημα που ανέφερες.

Δημοσ.
19 λεπτά πριν, kaliakman είπε

Όχι προτείνω να σβήσεις τελείως την addatbeg. Μήπως με μικρή αλλάγη στην addatend έχεις το ίδιο αποτέλεσμα με μια όμως συνάρτηση; Τα οφέλη για αυτό είναι πολλά. Έχεις ένα σημείο που μπορεί να γίνεται λάθος,όταν θες να κάνεις μια αλλάγη την κάνεις σε ένα μόνο σημείο κτλ.
Βάλε και τον κώδικα που γράφει στο αρχείο για να δούμε για το πρόβλημα που ανέφερες.

Τον εχω πολυ προχειρα ισα για να καταλαβω πως λειτουργει η fwrite επειδη δεν προλαβα να φτασω μεχρι εκει λογω το παραπανω προβληματος.

Δημοσ.
Μόλις τώρα, matheostsik είπε

Τον εχω πολυ προχειρα ισα για να καταλαβω πως λειτουργει η fwrite επειδη δεν προλαβα να φτασω μεχρι εκει λογω το παραπανω προβληματος.

Μήπως εδώ είναι το πρόβλημα σου? Όταν φτιάχνεις το αρχείο το έχεις ανοίξει να το δεις; Είναι καλά γραμμένο; Δηλαδή η τελευταία γραμμή είναι όντως αυτό που θες;

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...