FILE *fopen(const char *fname, const char *mode) void fclose(file *f) void fflush(file *f)

Σχετικά έγγραφα
Αρχεία εδοµένων. Προγραµµατισµός Ι 1

Διάλεξη 18η: Διαχείρηση Αρχείων

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διαδικασιακός Προγραμματισμός

Βιβλιοθήκη stdio. Προγραμματισμός II 1

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. ( ιάλεξη 13) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

ιαφάνειες παρουσίασης #6 (β)

Βιβλιοθήκη stdio. Προγραμματισμός II 1

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

Επεξεργασία Αρχείων Κειµένου

Ανάπτυξη και Σχεδίαση Λογισμικού

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Μεθόδων Επίλυσης Προβλημάτων

Ενδεικτική περιγραφή μαθήματος

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Η/Υ (ΤΛ2007 )

Ι Αρχεία δεδομένων, μέρος δεύτερο: δυαδικά αρχεία ΙΙ Δομές δεδομένων (struct)

Εργαστήριο 9: Αρχεία

Εισαγωγή στον Προγραμματισμό

Η γλώσσα προγραμματισμού C Χειρισμός αρχείων

Περιεχόμενα. Πρόλογος... 21

scanf() scanf() stdin scanf() printf() int float double %lf float

Προγραμματισμός σε C. Αρχεία κειμένου (Text files)

Αρχεία. Προγραμματισμός II 1

ΕΠΕΞΕΡΓΑΣΙΑ ΑΡΧΕΙΩΝ Λέµε αρχείο

Περιεχόµενα. Πρόλογος... 15

Προγραμματισμός Ι (ΗΥ120)

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Προγραμματισμός Ι. Χαρακτήρες. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Προγραμματισμός Ι (ΗΥ120)

Δομημένος Προγραμματισμός (ΤΛ1006)

ΑΡ Χ Ε Ι Α Κ Ε Ι Μ Ε Ν Ο Υ (text files)

Προγραμματισμός H/Y Ενότητα 7: Αρχεία. Επικ. Καθηγητής Συνδουκάς Δημήτριος Τμήμα Διοίκησης Επιχειρήσεων (Γρεβενά)

int a[5]; a[0] a[1] a[2] a[3] a[4] 15/10/2009

Ανάπτυξη και Σχεδίαση Λογισμικού

H ΓΛΩΣΣΑ C. Μάθηµα 16: Είσοδος/Έξοδος: Συναρτήσεις Eξόδου. ηµήτρης Ψούνης

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Περιεχόμενα. Πρόλογος... 17

Συναρτήσεις πρότυπης βιβλιοθήκης 1. Μερικές συνήθεις συναρτήσεις βιβλιοθήκης int atoi(const char *p) int fclose(file *fp)

Προγραμματισμός σε C. Αρχεία κειμένου (Text files)

Προγραμματισμός Ι (ΗΥ120)

Αρχεία & Ρεύματα ΑΡΧΕΙΑ & ΡΕΥΜΑΤΑ. Γεώργιος Παπαϊωάννου ( ) gepap@aueb.gr

Δομημένος Προγραμματισμός

Αρχές Προγραμματισμού

Ι Ανασκόπηση και εμβάθυνση Μερικά πιο προχωρημένα θέματα. ΙΙ Τα αρχεία δεδομένων στη C

Προγραµµατισµός Ι (ΗΥ120)

Ανάπτυξη και Σχεδίαση Λογισμικού

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Κεφάλαιο VΙ: Προσπέλαση Αρχείων. 5.1 Αρχεία δεδομένων.

Προγραµµατισµός. Αρχεία

4ο σετ σημειώσεων - Χειρισμός αρχείων και structs

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Διάλεξη 20: Χαμηλού Επιπέδου Προγραμματισμός II

Προγραμματισμός Η/Υ (ΤΛ2007 )

Κεφάλαιο Αλφαριθµητικές Σειρές Χαρακτήρων (Strings)

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραµµατισµός Ι 1

Εγχειρίδιο Συναρτήσεων. Socket *sopen(const int type, const int protocol, const char *host, const char *service)

Προγραμματισμός Ι (ΗΥ120)

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

#define, 70, 575 #elif, 580 #else, 580 #endif, 580 #error, 584 #if, 580 #ifdef, 583 #ifndef, 580, 583 #include, 70, 227, 574 #undef, 579

S, (5, -3, 34, -23, 7) ( *, _

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

Η γλώσσα προγραμματισμού C

Διαδικαστικός Προγραμματισμός

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

ΑΡΧΕΙΑ ΚΕΙΜΕΝΟΥ ΣΤΗΝ C

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Διαδικασιακός Προγραμματισμός

Προγραμματισμός Ι (ΗΥ120)

Σύνθετοι Τύποι εδοµένων. Προγραµµατισµός Ι 1

Προγραμματισμός Η/Υ (ΤΛ2007 )

Επανάληψη για τις Τελικές εξετάσεις

Η γλώσσα προγραμματισμού C

Δομημένος Προγραμματισμός (ΤΛ1006)

οµές (structures) Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: Πίνακες δοµών, δείκτες σε δοµές, και αυτοαναφορικές δοµές.

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Κλείδωμα αρχείων (file locking) Προγραμματισμός II 1

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διαδικασιακός Προγραμματισμός

Αρχεία. Προγραμματισμός II 1

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Προγραμματισμός Ι (HY120)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Προγραμματισμός συστημάτων UNIX/POSIX. Ανακατευθύνσεις (redirections)

C: Από τη Θεωρία στην Εφαρμογή

Βιβλιοθήκες Αφηρημένοι τύποι δεδομένων. Προγραμματισμός II 1

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 2 Ο. Εισαγωγή στην C Εντολές εξόδου Εντολές εισόδου Μορφοποιητές ΣΙΝΑΤΚΑΣ Ι. ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Transcript:

Προγραµµατισµός Ι (ΗΥ120) ιάλεξη 19: Αρχεία

Μόνιµη αποθήκευση δεδοµένων Η µνήµη (RAM) του Η/Υ κρατά δεδοµένα µόνο όσο της δίνεται µια ικανοποιητική παροχή ρεύµατος. Τα περιεχόµενα της µνήµης χάνονται (αµέσως) µε το που διακοπεί η τροφοδοσία ρεύµατος στον Η/Υ. Υπάρχει ανάγκη για την µόνιµη αποθήκευση δεδοµένων (των προγραµµάτων) ώστε αυτά να εξακολουθούν να υφίστανται αφού σβήσει ο Η/Υ. Αυτό επιτυγχάνεται µε µαγνητικά/οπτικά µέσα. Τα δεδοµένα «γράφονται» αλλάζοντας είτε την µαγνητική κατεύθυνση είτε την επιφανειακή δοµή του υλικού (µαγνητική ταινία, µαγνητικός δίσκος, οπτικός δίσκος, κλπ) έτσι ώστε να µπορεί να γίνει διαχωρισµός µεταξύ των καταστάσεων 0 και 1. 2

Μοντέλο πρόσβασης Τι βλέπει ο προγραµµατιστής όταν προσπελαύνει κύρια µνήµη; 3 Πίνακας από bytes µε άµεση πρόσβαση σε όλα τα στοιχεία µε το ίδιο κόστος (direct access). Όµως η πρόσβαση στα µόνιµα µέσα αποθήκευσης είναι πολύ πιο αργή και διαφορετική στη φύση της,, απαιτώντας πολύπλοκες λειτουργίες διαχείρισης. Για αυτό το λόγο (κυρίως) τα µέσα µόνιµης αποθήκευσης χρησιµοποιούνται µέσα από ένα ειδικό υποσύστηµα λογισµικού: το σύστηµα αρχείων. Το µοντέλο που δίνεται στον προγραµµατιστή για τα µέσα αποθήκευσης είναι µια ακολουθία από bytes µε σειριακή πρόσβαση (sequential access).

Σχετικές συναρτήσεις #include <stdio.h> 4 FILE fopen(const char *fname, const char *mode); void fclose(file *f); void fflush(file *f); int fgetc(file *f); int fputc(int c, FILE *f); int fscanf(file *f, const char *fmt, ); int fprintf(file *f, const char *fmt, ); size_t fread(const void *ptr, size_t size, size_t n, FILE *f); size_t fwrite(const void *ptr, size_t size, size_t n, FILE *f); int fseek(file *f, long int offset, int whence); int feof(file *f); int ferror(file *f); void clearerr(file *f);

Βασικές συναρτήσεις FILE *fopen(const char *fname, const char *mode) 5 άνοιγµα του αρχείου µε όνοµα fname σύµφωνα µε τον προσδιορισµό mode και επιστροφή δείκτη σε αντίστοιχη δοµή πρόσβασης Επιστρέφει NULL αν απέτυχε (πρέπει να ελέγχεται) void fclose(file *f) κλείσιµο της δοµής πρόσβασης αρχείου f (που έχει επιστραφείαπόεπιτυχηµένηκλήσητηςfopen) void fflush(file *f) µονιµοποίηση αλλαγών που έγιναν στο αρχείο, χωρίς να γίνει κλείσιµο του αρχείου σε κάποια συστήµατα αρχείων, η fclose δεν κάνει fflush

Προσδιορισµοί της fopen "r" "w" άνοιγµα αρχείου (που ήδη υπάρχει) για ανάγνωση άνοιγµα αρχείου που ήδη υπάρχει για εγγραφή (µε διαγραφή των δεδοµένων που υπάρχουν) ή δηµιουργία νέου αρχείου αν αυτό δεν υπάρχει "a" άνοιγµα αρχείου που υπάρχει για εγγραφή, αποκλειστικά µε προσθήκη στο τέλος του αρχείου ή δηµιουργία νέου αρχείου αν αυτό δεν υπάρχει "r+" "w+" "a+" "r" µε εγγραφή, χωρίς δηµιουργία νέου αρχείου "w" µε ανάγνωση "a" µε ανάγνωση 6 Μη επιτρεπτός προσδιορισµός (mode) οδηγεί σε επιστροφή λάθους (τιµής 0 / NULL) από την fopen.

Βασικές συναρτήσεις int fgetc(file *f) ανάγνωση του «επόµενου» byteαπό το αρχείο (ή EOF) int fputc(int c, FILE *f) γράψιµο του «επόµενου» byte στο αρχείο int fscanf(file *f, const char *frmt, ) ανάγνωση bytes από το αρχείο σύµφωνα µε τον προσδιορισµό frmt και αποθήκευση τιµών στις µεταβλητές των οποίων οι διευθύνσεις δίνονται σαν παράµετροι Σε αντιστοιχία µε την scanf int fprintf(file *f, const char *frmt, ) γράψιµο bytes στο αρχείο σύµφωνα µε τον προσδιορισµό frmt Σε αντιστοιχία µε την printf 7

Βασικές συναρτήσεις size_t fread(const void *p, size_t size, 8 size_t n, FILE *f) ανάγνωση από n αντικείµενα µεγέθους size bytes και αποθήκευση στη µνήµη, αρχίζοντας από την διεύθυνση p επιστρέφει τον αριθµό των αντικειµένων που διαβάστηκαν επιτυχώς size_t fwrite(const void *p, size_t size, size_t n, FILE *f) γράψιµο από n αντικείµενα µεγέθους size bytes στο αρχείο, αρχίζοντας από την διεύθυνση p επιστρέφει τον αριθµό των αντικειµένων που γράφτηκαν επιτυχώς

Βασικές συναρτήσεις int feof(file *f) επιστρέφει τιµή!0 αν η προηγούµενη πράξη προσπάθησε να «περάσει» το µέγεθος του αρχείου, διαφορετικά 0 int ferror(file *f) επιστρέφει τιµή!0 αν παρουσιαστεί κάποιο πρόβληµα µε τις πράξεις πρόσβασης για το συγκεκριµένο αρχείο (ο λόγος της αποτυχίας αποθηκεύεται ως ακέραιος στην καθολική µεταβλητή errno, και το αντίστοιχο µήνυµα λάθουςεπιστρέφεταιµέσωτηςstrerror) int clearerr(file *f) επαναφέρει την κατάσταση πρόσβασης σε «κανονική», αγνοώντας τυχόν προηγούµενο πρόβληµα πρόσβασης 9

Σειριακή πρόσβαση Για κάθε αρχείο διατηρείται (εσωτερικά) µια µεταβλητή (δείκτης) που υποδεικνύει την θέση στο αρχείο από την οποία θα αρχίσει η επόµενη πράξη (ανάγνωσης/εγγραφής). Κάθε πράξη ανάγνωσης ή εγγραφής αυξάνει την τιµή του δείκτη κατά τον αριθµό των bytes που διαβάστηκαν από το αρχείο ή γράφτηκαν στο αρχείο. Ότανοδείκτηςφτάσειτοτέλοςτουαρχείου,οιπράξεις ανάγνωσης δεν εκτελούνται και επιστρέφουν EOF ή/και κωδικό λάθους Οι πράξεις εγγραφής απλά επεκτείνουν το µέγεθος του αρχείου όσο χρειάζεται. Πρέπει πάντα να γίνεται έλεγχος της τιµής που επιστρέφουν οι πράξεις πρόσβασης σε αρχεία. 10

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 11 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 12 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 13 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 14 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 15 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 16 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 17 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 18 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 19 fputc('!',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

Βασικές συναρτήσεις Ο δείκτης µπορεί να επανατοποθετηθεί σε κάποιο σηµείο του αρχείου µέσω της fseek. int fseek(file *f, long offset, int whence) τοποθέτηση σηµείου ανάγνωσης/εγγραφής στην θέση offset και σε σχέση µε τον προσδιορισµό whence Η τιµές για την παράµετρο whence: SEEK_SET (από την αρχή του αρχείου) SEEK_CUR (από την τρέχουσα θέση) SEEK_END (από το τέλος του αρχείου) Επιστρέφει 0 εάν επιτύχει, διαφορετικά -1. 20

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 21 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 22 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 23 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 24 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 25 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'e' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 26 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' 'l' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 27 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' ' ' 'l' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 28 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' ' ' 'y' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 29 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' ' ' 'y' 'o' '!'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 30 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' ' ' 'y' 'o' 'u'

FILE *f; char c; f = fopen("test.txt","r+"); exit(1); 31 fseek(f,-1,seek_end); fseek(f,-5,seek_cur); fputc('i',f); fflush(f); fputc(' ',f); fflush(f); fputc('y',f); fflush(f); fputc('o',f); fflush(f); fputc('u',f); fflush(f); αρχείο "test.txt" 'h' 'i' ' ' 'y' 'o' 'u'

#include <stdio.h> int main(int argc, char *argv[]) { FILE *f; char c; f = fopen(argv[1],"w"); return(1); do { c = getchar(); fputc(c,f); } while (c!= '~'); fflush(f); 32 } f = fopen(argv[1],"r"); while (1) { c = fgetc(f); if (feof(f)) break; putchar(c); } return(0);

#include <stdio.h> int main(int argc, char *argv[]) { FILE *f; char s[64]; f = fopen(argv[1],"w"); return(1); do { scanf("%63s",s); fprintf(f,"%s ",s); } while (strcmp(s,"end")); fflush(f); κενός χαρακτήρας ως διαχωριστικό ανάµεσα στα δύο αλφαριθµητικά 33 } f = fopen(argv[1],"r"); while (1) { fscanf(f,"%63s",s); if (feof(f)) break; printf("%s ",s); } return(0);

Αποθήκευση binary / ASCII Μπορούµε να αποθηκεύσουµε τα δεδοµένα σε µορφή binaryή σε µορφή χαρακτήρων ASCII (text). Για την ίδιαπληροφορία διαφέρειο αριθµός και φυσικά(!) οι τιµές των bytes που γράφονται.. Π.χ. int i=1; binary: x00 0x00 0x00 0x01 ascii: 0x31 Π.χ. int i=100000000; binary: 0x3Β 0x9Α 0xCA 0x00 ascii: 0x31 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 34

Αποθήκευση binary Γίνεται µε την συνάρτηση fwrite. εν απαιτούνται (απαραίτητα) διαχωριστικά bytes καθώς για κάθε τύπο δεδοµένων γράφεται ένας συγκεκριµένος αριθµός bytes Ακριβώς όσα bytes αντιστοιχούν στο µέγεθος του τύπου. Κατά την ανάγνωση, µέσω fread, διαβάζονται όσα bytes αντιστοιχούν στο µέγεθος του τύπου. 35 Υπάρχει πρόβληµα ασυµβατότητας, αν τα δεδοµένα γράφονται / διαβάζονται από προγράµµατα που εκτελούνται σε περιβάλλοντα µε διαφορετικές συµβάσεις: (α) για τα µεγέθη βασικών και σύνθετων τύπων ή/και (β) την αποθήκευση τους στην µνήµη.

f=fopen("test","w"); i=1; j=1000000000; fwrite((void*)&i,sizeof(int),1,f); 36 fwrite((void*)&j,sizeof(int),1,f); fflush(f); τα όρια µεταξύ των δεδοµένων δίνονται έµµεσα από το µέγεθος των τύπων 0x01 0x00 0x00 0x00 0x00 0xCA 0x9A 0x3Β αρχείο "test"

Συµβάσεις κωδικοποίησης δεδοµένων Για να επιτευχθεί µεταφερσιµότητα των δεδοµένων, υιοθετούνται κοινές συµβάσεις εξωτερικής αναπαράστασης, για το πως αποθηκεύονται τιµές όλων των βασικών τύπων δεδοµένων µε τρόπο που είναι ανεξάρτητος της µεθόδου αποθήκευσης δεδοµένων στην µνήµη του εκάστοτε περιβάλλοντος εκτέλεσης (γλώσσα, µεταφραστής,επεξεργαστής). Το ίδιο πρόβληµα πρέπει να λυθεί για να επιτευχθεί ανταλλαγή δεδοµένων πάνω από δίκτυο. Μια συνηθισµένη λύση: αποθήκευση σε µορφή ASCII. 37

Αποθήκευση ASCII Γίνεται µε την συνάρτηση fprintf. Απαιτείται η εισαγωγή επιπλέον χαρακτήρων µορφοποίησης έτσι ώστε να οριοθετούνται τα διάφορα δεδοµένα που αποθηκεύονται. Ως διαχωριστικό χρησιµοποιούνται συνήθως οι χαρακτήρες ' ' ή '\n', όπως και για τις τιµές που εκτυπώνουµε στην οθόνη µέσω printf, για να µπορεί ο χρήστης να εντοπίζει (οπτικά) τον τερµατισµό µιας τιµής και την αρχή της επόµενης. Χρειάζεται προσοχή για τον σωστό χειρισµό των «διαχωριστικών» χαρακτήρων που τυχόν δηµιουργούνται (αναγνώριση ότι δεν είναι ένα κανονικό γράµµα/ψηφίο των δεδοµένων). 38

f=fopen("test","w"); i=1; j=1000000000; fprintf(f,"%d %d",i,j); 39 fflush(f); κενός χαρακτήρας ως διαχωριστικό ανάµεσα στα δύο αλφαριθµητικά '1' ' ' '1' '0' '0' '0' '0' '0' '0' '0' '0' '0' αρχείο "test"

Σύµβαση γραψίµατος/ανάγνωσης Ανεξάρτητα µε την µορφή που γίνεται η αποθήκευση, binary ή ASCII, πρέπει να υπάρχει κοινή σύµβαση γραψίµατος και ανάγνωσης δεδοµένων την οποία να ακολουθεί τόσο ο κώδικας γραψίµατος όσο και ο κώδικας ανάγνωσης των δεδοµένων. Πρέπει να καθοριστούν: (α) η µορφή αποθήκευσης, (β) η κωδικοποίηση των δεδοµένων, καθώς και (γ) η σειρά (και η λογική) µε την οποία γράφονται τα δεδοµένα στο αρχείο και σύµφωνα µε την οποία θα διαβαστούν τα δεδοµένα από το αρχείο. Αυτή η σύµβαση πρέπει να τεκµηριωθεί κατάλληλα. Η µετατροπή πολύπλοκων δοµών σε αποθηκεύσιµη µορφή ονοµάζεται συχνά και «σειριοποίηση». 40

αποθήκευση δεδοµένων σε δοµές κυρίως µνήµης Η/Υ 41 σειριοποίηση αποσειριοποίηση αποθήκευση δεδοµένων σε «επίπεδη» µορφή

Παράδειγµα (σώσιµο και επαναφορά βάσης δεδοµένων σε αρχείο)

Πρόβληµα Ζητούµενο: επιθυµούµε να σώσουµε τα δεδοµένα που διαχειριζόµαστε µέσω της δοµής στην κυρίως µνήµη σε ένα αρχείο, καθώς και να επαναφέρουµε µια «προηγούµενη» κατάσταση ανά πάσα στιγµή διαβάζοντας τα δεδοµένα από το αντίστοιχο αρχείο. ιαδικασία εγγραφής διασχίζουµε την δοµή των δεδοµένων για κάθε στοιχείο / κόµβο που είναι υπό χρήση, πραγµατοποιούµε αντίστοιχη εγγραφή στο αρχείο ιαδικασία ανάγνωσης δηµιουργούµε µια «άδεια» δοµή για κάθε εγγραφή που διαβάζουµε από το αρχείο, προσθέτουµε ένα αντίστοιχο στοιχείο / κόµβο 43

44 αποµάκρυνση προσθήκη επόµενο στοιχείο προς αποθήκευση νέων δεδοµένων... στοιχεία υπό χρήση ελεύθερα στοιχεία

/* phone book */ #define N 100 45 struct entry { char used; char name[64]; char phone[64]; }; struct entry entries[n]; void phonebook_init() { int i; for (i=0; i<n; i++) { entries[i].used=0; } }

void phonebook_save_binary(const char *fname) { int i; FILE *f; } f = fopen(fname,"w"); exit(1); for (i=0; i<n; i++) { if (entries[i].used) { fwrite(&entries[i],sizeof(struct entry),1,f); } } 46 void phonebook_load_binary(const char *fname) { int i; FILE *f; char tag; } phonebook_init(); /* clean state */ f = fopen(fname,"r"); exit(1); i=0; while (fread(&entries[i],sizeof(struct entry),1,f)) { i++; }

Παρατήρηση Οι συναρτήσεις save και restore αποθηκεύουν τα δεδοµένα σε µορφή binary, και µάλιστα «ως έχουν» στην µνήµη του περιβάλλοντος εκτέλεσης του Η/Υ. Η υλοποίηση δεν επιτυγχάνει µεταφερσιµότητα δεδοµένων, π.χ. στην περίπτωση που το πρόγραµµα (ξανα)µεταφραστεί µε διαφορετικό µεταφραστή ή/και εκτελεστεί πάνω σε διαφορετική αρχιτεκτονική. Για να επιτευχθεί µεταφερσιµότητα πρέπει να ορίσουµε και να υλοποιήσουµε µια κωδικοποίηση που είναι ανεξάρτητη περιβάλλοντος εκτέλεσης. Μια «εύκολη» λύση: µετατρέπουµε τα δεδοµένα σε/από χαρακτήρες ASCII, µέσω fprintf/fscanf. 47

void phonebook_save_ascii(const char *fname) { int i; FILE *f; } f = fopen(fname,"w"); exit(1); for (i=0; i<n; i++) { if (entries[i].used) { fprintf(f,"%s %s\n",entries[i].name,entries[i].phone); } } 48 void phonebook_load_ascii(const char *fname) { int i,tag; FILE *f; } phonebook_init(); /* clean state */ f = fopen(fname,"r"); exit(1); i=0; while (fscanf(f,"%s %s",entries[i].name,entries[i].phone)==2) { entries[i].used = 1; i++; }

Σε µια σοβαρή εφαρµογή Θα γινόταν έλεγχος για περίπτωση αποτυχίας µετά από κάθε πράξη εγγραφής / ανάγνωσης αρχείου. Κατά την ανάγνωση θα γινόταν έλεγχος για το κατά πόσο υπάρχει πρόβληµα ακεραιότητας του αρχείου (για την αποφυγή ανάγνωσης αρχείων που δεν περιέχουν δεδοµένα του προγράµµατος ή αρχείων που έχουν «καταστραφεί»). Η αντικατάσταση των δεδοµένων του προγράµµατος θα γινόταν εφόσον η διαδικασία ανάγνωσης των δεδοµένων ολοκληρωνόταν επιτυχώς. 49

Παρένθεση (σώσιµο και επαναφορά βάσης δεδοµένων σε αρχείο)