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

Σχετικά έγγραφα
Δομημένος Προγραμματισμός (ΤΛ1006)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Προγραμματισμός I (Θ)

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

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

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

Διάλεξη 5η: Εντολές Επανάληψης

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

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

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

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

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

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

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

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

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

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

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

Πληροφορική & Τηλεπικοινωνίες. K18 - Υλοποίηση Συστημάτων Βάσεων Δεδομένων Εαρινό Εξάμηνο

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

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

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

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

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

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

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

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

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

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

ΕΝΤΟΛΕΣ ΕΠΑΝΑΛΗΨΗΣ. for (παράσταση_1; παράσταση_2; παράσταση_3) εντολή επόμενη εντολή

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

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

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

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

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

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

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

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

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

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

Πληροφορική & Τηλεπικοινωνίες Υλοποίηση Συστημάτων Βάσεων Δεδομένων - Χειμερινό Εξάμηνο Καθηγητής Δ. Γουνόπουλος

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Η-Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Εργαστήριο 1 Εισαγωγή στη C. Σοφία Μπαλτζή s.mpaltzi@di.uoa.gr

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

Στόχοι και αντικείμενο ενότητας. Πέρασμα Πίνακα σε Συνάρτηση (συν.) Πέρασμα Πίνακα σε Συνάρτηση. #8.. Ειδικά Θέματα Αλγορίθμων

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

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

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

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

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

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

Προγραμματιστικές τεχνικές

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

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

Πληροφορική & Τηλεπικοινωνίες K18 - Υλοποίηση Συστημάτων Βάσεων Δεδομένων Χειμερινό Εξάμηνο M. Χατζόπουλος. Προθεσμία: 19/01/2015

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

6. ΠΙΝΑΚΕΣ & ΑΛΦΑΡΙΘΜΗΤΙΚΑ

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

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

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

Transcript:

Τεχνολογικό Εκπαιδευτικό Ίδρυμα Κρήτης Σχολή Εφαρμοσμένων Επιστημών Τμήμα Ηλεκτρονικών Μηχανικών Τομέας Αυτοματισμού και Πληροφορικής Δομημένος Προγραμματισμός (ΤΛ1006) Δρ. Μηχ. Νικόλαος Πετράκης, Καθηγητής Εφαρμογών (npet@chania.teicrete.gr) Δέκατη τρίτη (13 η ) τρίωρη διάλεξη. Ιστοσελίδα Μαθήματος: https://eclass.chania.teicrete.gr/courses/el106 Εξάμηνο: Χειμερινό 2018-19

Μέθοδοι Αναζήτησης (Searching) Στόχος των αλγόριθμων αναζήτησης είναι η πιο αποτελεσματική συλλογή πληροφοριών που είναι αποθηκευμένες στην μνήμη ενός Η/Υ. Το πρόβλημα της αναζήτησης, στην πιο γενική του μορφή, αναφέρεται στην αναζήτηση κάποιου στοιχείου ενός συνόλου, που ικανοποιεί μια συνθήκη. 2

Σειριακή αναζήτηση Η πιο απλή μέθοδος αναζήτησης είναι αυτή της σειριακής αναζήτησης (sequential search) όπου συγκρίνονται διαδοχικά τα κλειδιά, των αντικειμένων του συνόλου στο οποίο διενεργείται η αναζήτηση, με το ζητούμενο κλειδί. Η διαδικασία τερματίζεται όταν διαπιστωθεί ότι κάποιο από τα κλειδιά είναι ίσο με το ζητούμενο ή όταν εξετασθούν όλα τα κλειδιά. Η συνάρτηση seqsearch που ακολουθεί υλοποιεί τον παραπάνω αλγόριθμο. Για να απλοποιηθεί η συνθήκη ελέγχου της εντολής επανάληψης ο αλγόριθμος προτείνει την καταχώρηση του κλειδιού μια θέση μετά το τέλος του πίνακα. 3

Παράδειγμα σειριακής αναζήτησης #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 20 #define L 10 #define K 50 int seqsearch (int *a, int n, int key); Γέμισμα πίνακα με ψευδοτυχαίες ακέραιες τιμές από το 10 έως το 50 και αναζήτηση της τιμής 30. // Μέγεθος πίνακα ακεραίων // Κάτω όριο και // άνω όριο ψευδοτυχαίων τιμών main() { int i,thesh, pin[n+1]; // Μια παραπάνω θέση srand((unsigned)time(null)); for (i=0; i<n; i++) pin[i]= L + rand()%(k-l+1); thesh = seqsearch(pin, N, 30); if (thesh > -1) printf("found at position %d\n\n",thesh); else printf("not FOUND.\n\n"); sestem("pause"); return 0; 4

Παράδειγμα σειριακής αναζήτησης int seqsearch (int *a, int n, int key) { int d=0; a[n]=key; while (a[d]!=key) d++; if (d==n) return -1; // Δεν υπάρχει else return d; // Υπάρχει στην θέση d Όταν συμβαίνουν συχνά ανεπιτυχείς αναζητήσεις είναι προτιμότερο να ταξινομούμε τα κλειδιά και να εφαρμόζουμε έναν τροποποιημένο σειριακό αλγόριθμο αναζήτησης. int seqsearch(int *a, int n, int key) { int d=0; a[n]=int_max; // INT_MAX = 2147483647 while (a[d]<key) // Maximum (signed) int value d++; if (d<n && a[d]==key) return d // Υπάρχει στην θέση d else return -1; // Δεν υπάρχει 5

Πολυπλοκότητα σειριακής αναζήτησης Για τεχνικές σειριακής αναζήτησης ισχύει ότι αν έχουμε n στοιχεία, στην χειρότερη περίπτωση θα εκτελεστούν (n+1) συγκρίσεις, στην μέση περίπτωση έχουμε (n+1)/2, και στην καλύτερη έχουμε 1 σύγκριση. Με άλλα λόγια η πολυπλοκότητα της μέσης και της χειρότερης περίπτωσης είναι O(n). Υπάρχουν όμως κι άλλοι αλγόριθμοι που είναι ταχύτεροι (ειδικά για μεγάλο αριθμό στοιχείων), οι οποίοι όμως υποθέτουν ότι το σύνολο των στοιχείων είναι γραμμικώς διατεταγμένο ως προς το κλειδί της αναζήτησης. 6

Δυαδική αναζήτηση (binary search) Η μέθοδος αυτή, η οποία μπορεί να εφαρμοστεί μόνο σε ταξινομημένα κλειδιά, διχοτομεί σε κάθε επανάληψη το μέρος του πίνακα που δεν έχει διερευνηθεί και περιορίζει την αναζήτηση στον μισό πίνακα. Έτσι μετά από lgn διχοτομήσεις, στην χειρότερη περίπτωση, είτε θα έχουμε εντοπίσει το ζητούμενο κλειδί είτε θα έχουμε καταλήξει ότι το κλειδί αυτό δεν υπάρχει. Επειδή, ο μέγιστος αριθμός συγκρίσεων που απαιτούνται για την αναζήτηση ενός κλειδιού είναι ο λογάριθμος με βάση το 2 του συνολικού αριθμού n των κλειδιών, η διαδικασία αυτή ονομάζεται και λογαριθμική αναζήτηση (logarithmic search). 0 1 2 n-2 n-1 bot mid = (bot + top)/2 top 7

Παράδειγμα δυαδικής αναζήτησης Η συνάρτηση binsearch που ακολουθεί αποτελεί την υλοποίηση του παραπάνω αλγόριθμου σε μη αναδρομική μορφή. int binsearch(int *a, int n, int key) { int bot, top, mid; bot = 0; top = n-1; while (bot <= top) { mid = (bot + top)/2; if (key < a[mid]) top = mid - 1; else if (key > a[mid]) bot = mid + 1; else return mid; return -1; 8

Ενώσεις Η ένωση (union) είναι ένας τύπος της C που μοιάζει με τη δομή. Μια ένωση έχει στοιχεία διαφορετικών τύπων, όπως η δομή, αλλά μόνο ένα από αυτά μπορεί να χρησιμοποιείται κάθε φορά. Για τα στοιχεία της ένωσης δεσμεύεται ένας κοινός χώρος μνήμης, ίσος με το μέγεθος του μεγαλύτερου στοιχείου. H ανάθεση τιμής σε ένα στοιχείο της ένωσης «γράφει» στην περιοχή μνήμης που μπορεί να υπήρχε τιμή για άλλο στοιχείο. Παράδειγμα: union shared { char c; int i; ; union shared generic_variable = {'@'; Χρησιμοποιούμε τον τελεστή μέλους (dot operator) για να προσπελαύνουμε τα μέλη της ένωσης. 9

Παράδειγμα #include <stdio.h> #define CHARACTER 'C' #define INTEGER 'I' #define FLOAT 'F' main() { struct generic_tag var; var.type = CHARACTER; var.shared.c = '$'; print_function(var); struct generic_tag{ char type; union shared_tag { char c; int i; float f; ; shared; void print_function(struct generic_tag gen); var.type = FLOAT; var.shared.f = (float)3.1415; print_function(var); var.type = 'x'; var.shared.i = 111; print_function(var); return 0; 10

Παράδειγμα (συνέχεια) void print_function(struct generic_tag gen) { printf("\n\nthe generic value is..."); switch(gen.type) { case CHARACTER: printf("%c", gen.shared.c); break; case INTEGER: printf("%d", gen.shared.i); break; case FLOAT: printf("%f", gen.shared.f); break; default: printf("an unknown type: %c\n", gen.type); break; return ; Αποτέλεσμα: The generic value is...$ The generic value is...3.1415 The generic value is...an unknown type: x 11

Ροές ή Ρεύματα Κειμένου (Text Streams ) Στη C ο όρος (text) stream ορίζει μία πηγή στοιχείων εισόδου, ή ένα προορισμό για στοιχεία εξόδου (μία ακολουθία bytes δεδομένων) και είναι συνώνυμο με το αρχείο (κειμένου). Δύο βασικά και οριζόμενα αυτόματα από τη C streams είναι το πληκτρολόγιο (keyboard) για είσοδο (input) [stdin], και η οθόνη (screen ή terminal), για έξοδο (output) [stdout], Τα μεγάλα προγράμματα μπορούν να έχουν πολλές πηγές εισόδου π.χ. Modems, CD drives, files, κλπ. Τα προγράμματα συνήθως διαβάζουν στοιχεία από μια πηγή και στέλνουν αποτελέσματα σε ένα προορισμό (που μπορεί να είναι πηγή στοιχείων για κάποιο άλλο πρόγραμμα). Στη C θα μπορούσαμε να χειριστούμε μια ροή είτε ως κειμένου (text) είτε ακόμα και ως δυαδική (binary). 12

Προκαθορισμένες ροές Η ΑΝSI C έχει τρεις προκαθορισμένες ροές: stdin (προκαθορισμένη είσοδος πληκτρολόγιο), stdout (προκαθορισμένη έξοδος οθόνη), και stderr (προκαθορισμένη έξοδος λάθους οθόνη). Με printf() ή puts() χρησιμοποιούμε την stdout, με scanf() ή gets() λαμβάνουμε είσοδο από το πληκτρολόγιο, δηλ. την stdin. Οι περισσότερες συναρτήσεις της C, είτε χρησιμοποιούν τις προκαθορισμένες ροές, είτε απαιτούν τον προσδιορισμό της ροής από το χρήστη (π.χ. getc() / getchar(), putc() / putchar(), κλπ) 13

Προσπέλαση Αρχείων Μέχρι τώρα όποτε μιλούσαμε για αρχείο εισόδου θεωρούσαμε την πρότυπη (στάνταρτ) είσοδο και όποτε μιλούσαμε για αρχείο εξόδου θεωρούσαμε την πρότυπη έξοδο, που σε κάθε πρόγραμμα C ορίζονται αυτόματα από το τοπικό λειτουργικό σύστημα. Στην συνέχεια θα δούμε πως μπορούμε να προσπελάσουμε αρχεία που δεν είναι ήδη συνδεδεμένα με το πρόγραμμα. Π.χ. cat prog1.c prog2.c // συνενώνει ένα σύνολο κατονομαζόμενων // αρχείων στην οθόνη Το πρόβλημα είναι πως να οργανώσουμε το διάβασμα ή την εγγραφή των αναφερόμενων αρχείων - δηλαδή, πως να συνδέσουμε τα εξωτερικά ονόματα που έχει στο νου του ο χρήστης, με τις εντολές που διαβάζουν τα δεδομένα. 14

Βήματα για την Προσπέλαση Αρχείων Για να μπορεί να γραφτεί ή να διαβαστεί ένα αρχείο, πρέπει να ανοιχτεί με την συνάρτηση βιβλιοθήκης fopen(), η οποία παίρνει ένα εξωτερικό όνομα (όπως το prog1.c ή prog2.c) και επιστρέφει ένα δείκτη διεύθυνσης (pointer) για να χρησιμοποιηθεί στις επόμενες αναγνώσεις ή καταγραφές του αρχείου. Ο δείκτης αυτός, που λέγεται δείκτης διεύθυνσης αρχείου (file pointer), δείχνει μια δομή που περιέχει πληροφορίες για το αρχείο, όπως η θέση μιας περιοχής ενδιάμεσης αποθήκευσης (buffer), η τρέχουσα θέση χαρακτήρα στην περιοχή ενδιάμεσης αποθήκευσης, το αν γράφεται ή διαβάζεται το αρχείο, κι αν έχουν συμβεί λάθη ή αν έχει συναντηθεί το τέλος του αρχείου. Η μόνη δήλωση που χρειάζεται να γίνει για δείκτη αρχείου είναι: FILE *fp; 15

Βήματα για την Προσπέλαση Αρχείων Το πρωτότυπο της fopen() είναι: FILE *fopen(char *name, char *mode); Η κλήση της fopen σε ένα πρόγραμμα είναι: fp = fopen (name, mode); // "r" ανάγνωση, "w" εγγραφή, "a" προσθήκη, "b" δυαδικό Προσοχή: Ο προεπιλεγμένος τύπος αρχείων είναι τα αρχεία κειμένου. π.χ. η εντολή fopen("test.dat", "wb"); ανοίγει για εγγραφή ένα δυαδικό αρχείο, ενώ η εντολή fopen("test1.txt", "w"); ανοίγει για εγγραφή ένα αρχείο κειμένου. Το επόμενο που χρειάζεται είναι ένας τρόπος για την ανάγνωση ή την καταγραφή στο αρχείο όταν αυτό είναι ανοιχτό. Υπάρχουν διάφορες δυνατότητες, από τις απλούστερες είναι οι: getc putc // int getc(file *fp); // int putc(int c, FILE *fp); // EOF για τέλος αρχείου ή λάθος Για φορμαρισμένη είσοδο και έξοδο αρχείων, μπορούν να χρησιμοποιηθούν οι συναρτήσεις: fscanf // int fscanf(file *fp, char *format ); fprintf // int fprintf(file *fp, char *format ); 16

Βήματα για την Προσπέλαση Αρχείων Η αντίστροφη της fopen() είναι η συνάρτηση : int fclose(file *fp); η οποία διακόπτει τη σύνδεση ανάμεσα στο δείκτη αρχείου και το εξωτερικό όνομα που έχει καθοριστεί με την fopen(), ελευθερώνοντας το δείκτη αρχείου. Τα λειτουργικά έχουν όριο στον αριθμό των ταυτόχρονα ανοικτών αρχείων. Σε αρχεία εξόδου αδειάζει την περιοχή ενδιάμεσης αποθήκευσης στην οποία η putc() συλλέγει την έξοδο. Κατά τον κανονικό τερματισμό του προγράμματος, η fclose() καλείται, αυτόματα για όλα τα ανοικτά αρχεία. 17

Ανίχνευση τέλους αρχείου Όταν δεν γνωρίζουμε πόσα στοιχεία περιέχει ένα αρχείο και θέλουμε να διαβάσουμε τα δεδομένα από την αρχή μέχρι το τέλος του, θα πρέπει να ανιχνεύσουμε το τέλος του αρχείου. Όταν διαβάζουμε από ένα αρχείο κειμένου χαρακτήρα προς χαρακτήρα, μπορούμε να ψάξουμε το χαρακτήρα τέλους αρχείου. Η συμβολική σταθερά ΕΟF ως -1 (ή ένα byte όλο άσσους) έχει τιμή που δε χρησιμοποιείται ποτέ από ένα πραγματικό χαρακτήρα. Όταν μία συνάρτηση διαβάσει το ΕΟF από μία ροή κειμένου, τότε ξέρουμε ότι έχουμε φτάσει στο τέλος του αρχείου. while ((c = getc(fp))!= ΕΟF ) Σε μία δυαδική ροή, ένα byte δεδομένων θα μπορούσε να έχει αυτή τη τιμή, γι αυτό μπορούμε να χρησιμοποιήσουμε τη συνάρτηση feof() για δυαδικά αρχεία αλλά και για αρχεία κειμένου. int feof(file *fp); Το όρισμα fp είναι ο δείκτης σε FILE που επιστρέφεται από τη fopen() H feof() επιστρέφει 0 αν δεν συναντήσει το τέλος του αρχείου και μη μηδενική τιμή αν το συναντήσει. Εάν μία κλήση της feof() ανιχνεύσει το τέλος του αρχείου τότε πρέπει ή να κάνουμε rewind(), fseek() ή να κλείσουμε και να ανοίξουμε το αρχείο ξανά. 18

Άλλες συναρτήσεις διαχείρισης αρχείου int remove(const char *filename); Εάν το αρχείο υπάρχει, διαγράφεται και επιστρέφει 0. Αν το αρχείο δεν υπάρχει ή είναι μόνο για ανάγνωση, επιστρέφει -1. int rename(const char *oldname, const char *newname); Επιστρέφει 0 σε επιτυχία. Αν το αρχείο δεν υπάρχει ή υπάρχει ήδη ένα αρχείο με το νέο όνομα ή επιχειρούμε να μετονομάσουμε σε διαφορετικό δίσκο τότε επιστρέφει -1. 19

#include <stdio.h> main(){ FILE *ifp, *ofp; char c; ifp = fopen("test.dat", "r"); ofp = fopen("out.dat", "w"); Παράδειγμα Να γίνει πρόγραμμα το οποίο θα διαβάζει χαρακτήρες από το αρχείο ifp ("test.dat") με getc() και θα τους αντιγράφει στο αρχείο ofp ("out.dat") με putc(). if (ifp == NULL) { printf("can not open input file\n"); return 1; if (ofp == NULL) { printf("can not open output file\n"); return 2; Προσοχή: Πάντα όταν προσπαθούμε να ανοίξουμε ένα αρχείο πρέπει να ελέγχουμε αν το άνοιγμα έγινε επιτυχώς. Σε αντίθετη περίπτωση (π.χ. αν δεν υπάρχει αρχείο με το όνομα που δώσαμε), η fopen επιστρέφει NULL. while((c = getc(ifp))!= EOF) putc(c, ofp); fclose(ifp); fclose(ofp); return 0; 20

Άσκηση: Να γίνει ένα πρόγραμμα που να αντιγράφει ένα αρχείο με κώδικα γραμμένο σε γλώσσα C, σε ένα άλλο αφαιρώντας όλα τα σχόλια (/* */). Θεωρήστε ότι τα σχόλια δεν είναι επάλληλα, δηλαδή φωλιασμένα το ένα μέσα στο άλλο. Συγκρίνετέ το με το πρόγραμμα που κάνει την ίδια δουλειά αντιγράφοντας, όμως, από την στάνταρτ είσοδο (stdin) στην στάνταρτ έξοδο (stdout) 21

#include <stdio.h> // program nocomment #define NO 0 // stdin stdout #define YES 1 #define NC-3 main() { int car, cp=nc, comment=no; printf("\n Δώστε κείμενο (^z για τέλος) :\n"); while ((car=getchar())!=eof) { if (comment==no) { if ((cp=='/')&&(car=='*')) { comment=yes; car=nc; else if (cp!=nc) putchar(cp); else if ((cp=='*')&&(car=='/')) { comment=no; car=nc; cp = car; if ((comment==no)&&(cp!=nc)) putchar(cp); return 0; 22

#include <stdio.h> // program nocomment #define NO 0 // test.c testnc.c #define YES 1 #define NC -3 main() { int car, cp=nc, comment=no; FILE *fps, *fpd; printf("\n ***Copy Files***\n"); if ((fps=fopen("test.c","r"))==null) { printf("\n File not found\n\n"); exit(1); if ((fpd=fopen("testnc.c","w"))==null) { printf("\n File not accessible\n\n"); exit (1); while ((car=getc(fps))!=eof) { if (comment==no) { if ((cp=='/')&&(car=='*')) { comment=yes; car=nc; else if (cp!=nc) putc(cp,fpd); else if ((cp=='*')&&(car=='/')) { comment=no; car=nc; cp = car; if ((comment==no)&&(cp!=nc)) putc(cp,fpd); fclose(fps); fclose(fpd); return 0; 23

Συνοπτικά Ανοίγετε ένα αρχείο πριν επιχειρήσετε να διαβάσετε ή να γράψετε σε αυτό. Πάντοτε να ελέγχετε ότι η πρόσβαση σε ένα αρχείο ήταν σωστή. Κλείνετε όλα τα αρχεία που έχετε ανοίξει και δεν χρειάζεστε πλέον. Την επόμενη εβδομάδα επίλυση Αποριών / Επαναληπτικές Ασκήσεις. Για απορίες θα είμαι στο γραφείο μου (Νο 5, παλιό κτήριο), την Τρίτη 22 Ιανουαρίου 2019 από τις 9:00 έως τις 12:00. Εξέταση την Τετάρτη 23 Ιανουαρίου 2019 από τις 8:00! Καλό διάβασμα και καλή επιτυχία! 24