Τεχνικές αρχείων

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Βοηθητική μνήμη

Αρχεία

Επεξεργασία σειριακών αρχείων

Αρχεία τυχαίας προσπέλασης

Επεξεργασία αρχείων στη C

Η επεξεργασία αρχείων στη C γίνεται με βάση συναρτήσεις του αφηρημένου τύπου δεδομένων FILE * που ορίζονται στην επικεφαλίδα stdio.h. Για να αποκτήσει το πρόγραμμα πρόσβαση σε ένα αρχείο πρέπει να καλέσει τη συνάρτηση:
fopen(μονοπάτι αρχείου, τύπος πρόσβασης)

Η συνάρτηση επιστρέφει μια τιμή τύπου FILE * την οποία το πρόγραμμα χρησιμοποιεί για πρόσβαση στο αρχείο. Αν η πρόσβαση στο αρχείο δεν είναι δυνατή (π.χ. το αρχείο στο οποίο ζητήθηκε ανάγνωση δεν υπάρχει, ένας κατάλογος από το μονοπάτι δεν υπάρχει, το αρχείο το οποίο ζητήθηκε εγγραφή δεν το επιτρέπει) τότε η συνάρτηση fopen επιστρέφει την τιμή NULL.

Ο τύπος πρόσβασης μπορεί να είναι ένας από τους παρακάτω:
Τύπος πρόσβασηςΠρόσβαση
"r"Ανάγνωση (read)
"w"Εγγραφή (write)
"a"Προσθήκη (append)
"r+w"Ανάγνωση και εγγραφή

Στο τέλος της επεξεργασίας του αρχείου πρέπει να καλέσουμε τη συνάρτηση fclose(f) (όπου f η τιμή που επέστρεψε η fopen) για να δηλώσουμε στη βιβλιοθήκη και το λειτουργικό σύστημα να απελευθερώσουν τους πόρους που είχαν δεσμευτεί για την επεξεργασία του αρχείου.

Σειριακή επεξεργασία αρχείων ASCII στη C

Η σειριακή επεξεργασία αρχείων που περιέχουν χαρακτήρες ASCII στη μορφή που τους διαβάζουν και γράφουν οι άνθρωποι γίνεται με βάση τις παρακάτω συναρτήσεις:
fprintf(FILE *stream, char *format, ...)
Τυπώνει φορμαρισμένα σε αρχείο.
fscanf(FILE *stream, char *format, ...)
Διαβάζει φορμαρισμένα από αρχείο.
fgetc(FILE *stream)
Διαβάζει έναν χαρακτήρα από αρχείο.
fputc(char c, FILE *stream)
Γράφει έναν χαρακτήρα σε αρχείο.
feof(FILE *stream)
Επιστρέφει αληθές αν έχει ανιχνευτεί το τέλος του αρχείου.
Οι παραπάνω συναρτήσεις είναι αντίστοιχες με τις printf, scanf, getchar, putchar, μόνο που αντί για την είσοδο και έξοδο του προγράμματος δουλεύουν σε αρχεία.

Το παρακάτω πρόγραμμα γράφει στο αρχείο codes.txt τους χαρακτήρες ASCII που διαβάζονται και τους αντίστοιχους κωδικούς τους:

#include <stdio.h>

main()
{
	FILE *f;
	int i;

	f = fopen("codes.txt", "w");
	for (i = ' '; i < '~'; i++)
		fprintf(f, "Character: %c  code:%d\n", i, i);
	fclose(f);
}

Σημείωση: οι συναρτήσεις getc και putc είναι γρήγορες εκδόσεις των gfetc και fputc.

Σειριακή επεξεργασία κωδικοποιημένων αρχείων στη C

Για λόγους απόδοσης συχνά τα αρχεία δεν περιέχουν παράσταση των τιμών των δεδομένων με τη μορφή που τα εισάγουν και τα διαβάζουν οι άνθρωποι (αρχεία ASCII (ASCII files)), αλλά με τη μορφή που φυλάσσονται στη μνήμη του υπολογιστή (δυαδικά αρχεία (binary files)). Ο τρόπος αυτός φύλλαξης έχει τις παρακάτω επιπτώσεις: Μεταφορά στοιχείων μεταξύ της κεντρικής μνήμης και αρχείων γίνεται με τις συναρτήσεις:
fread(void *ptr, size_t size, size_t nitems, FILE *stream)
Μεταφέρει nitems στοιχεία μεγέθους size από το αρχείο f στη θέση μνήμης ptr.
fwrite(void *ptr, size_t size, size_t nitems, FILE *stream)
Μεταφέρει nitems στοιχεία μεγέθους size από τη θέση μνήμης ptr στο αρχείο f.
Το παρακάτω παράδειγμα γράφει τον πίνακα tbl στο αρχείο f:
	int tbl[100];

	fwrite(tbl, sizeof(int), 100, f);

Επεξεργασία αρχείων τυχαίως προσπέλασης στη C

Η βιβλιοθήκη της C μας δίνει τη δυνατότητα μετακίνησης και σε τυχαία σημεία του αρχείου με βάση τις συναρτήσεις fseek και ftell:
int fseek(FILE * f, long pos, int whence);
Ορίζει ως επόμενη θέση για ανάγνωση ή εγγραφή στο αρχείο f τη θέση pos. Η θέση ορίζεται ανάλογα με τη σταθερά που θα οριστεί στη whence:
SEEK_CUR
από την τρέχουσα θέση στο αρχείο,
SEEK_END
από το τέλος του αρχείου,
SEEK_SET
από την αρχή του αρχείου.
Η fseek επιστρέφει -1 αν η θέση που δώθηκε δεν είναι σωστή, αλλιώς επιστρέφει 0. Το παρακάτω παράδειγμα μεταφέρει τη θέση ανάγνωσης στον 10ο ακέραιο του αρχείου f:
	fseek(f, 10 * sizeof(int), SEEK_SET);
long ftell(FILE *f)
Επιστρέφει την τρέχουσα θέση ανάγνωσης/εγγραφής στο αρχείο f.

Βιβλιογραφία

Ασκήσεις

Άσκηση 7

  1. Να υλοποιηθεί σε C το πρόγραμμα addphone το οποίο ζητά από το χρήστη ένα όνομα και ένα τηλέφωνο και τα προσθέτει σε αρχείο καθώς και το πρόγραμμα getphone το οποίο ζητά από το χρήστη ένα όνομα και αν αυτό βρίσκεται στο αρχείο τυπώνει το τηλεφωνό του.
    Παράδειγμα:
    C>addphone
    Name:EKAB
    Phone:166
    
    C>getphone
    Name:EKAB
    Phone=166