1 / 36

Γενίκευση ( genericity ) Ι

Γενίκευση ( genericity ) Ι.

haven
Download Presentation

Γενίκευση ( genericity ) Ι

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Γενίκευση (genericity) Ι Ο λόγος που επιδιώκουμε τη δυνατότητα γενίκευσης μιας κλάσης (ή συνάρτησης) είναι το να μπορούμε να κάνουμε τον ορισμό της χωρίς να προσδιορίσουμε τον τύπο ενός ή περισσοτέρων μελών της (παράμετροι). Έτσι, θα μπορούμε να προσαρμόζουμε την κλάση (συνάρτηση)σε διαφορετικές περιπτώσεις χρήσης της χωρίς να επιβάλλεται να την ξαναγράψουμε. ΠΑΡΑΔΕΙΓΜΑ Πρέπει να γράψουμε τον κώδικα για μια ουρά ή μια στοίβα. Μπορούμε εύκολα να ορίσουμε μια ουρά ακεραίων, αλλά τι γίνεται όταν θέλουμε σε μία ουρά να χρησιμοποιούμε αντικείμενα τύπου date; Κάθε γλώσσα αντιμετωπίζει το παραπάνω πρόβλημα και με διαφορετικό τρόπο. Τμ. Πληροφορικής, Α.Π.Θ.

  2. Γενίκευση (genericity) ΙΙ Στη Smalltalk όπου ο έλεγχος τύπων γίνεται σε χρόνο εκτέλεσης ο πολυμορφισμός δεν περιορίζεται στις ιεραρχίες των κλάσεων, αλλά κάθε κλάση μπορεί να αντικατασταθεί από μία άλλη. Έτσι, η γενίκευση γίνεται εύκολα. Στη C++ έχουμε έλεγχο τύπων σε χρόνο μεταγλώττισης. Υπάρχουν δύο τρόποι για την επίτευξη γενίκευσης: • με χρήση κληρονομικότητας και πολυμορφισμού ορίζοντας κλάση, που χειρίζεται δείκτες σε αντικείμενα • με χρήση παραμετροποιήσιμων τμημάτων κώδικα, των επονομαζόμενων templates Η πρώτη μέθοδος (βλ. παράδειγμα παρακάτω)συνοδεύεται από έναν κίνδυνο με την κατ΄ απαίτηση προσαρμογή (casting) που χρειάζεται στην ανάκτηση του τύπου των αντικειμένων που χειρίζεται η κλάση με τους δείκτες. Τμ. Πληροφορικής, Α.Π.Θ.

  3. Γενίκευση (genericity) ΙΙΙ class GenericObject {}; //stack.h class Stack { GenericObject* data[50]; int nElements; public: Stack() { nElements=0; } void Push(GenericObject* elem); GenericObject* Pop(); int Number(); int Empty(); }; #include “stack.h” //stack.cpp void Stack::Push(GenericObject* elem) { data[nElements]=elem; nElements++; } GenericObject* Stack::Pop() { nElements--; return data[nElements]; } int Stack::Number() { return nElements; } int Stack::Empty() { return (nElements==0); } #include <iostream.h> //sta_use.cpp #include “stack.cpp” class IntObj:public GenericObject { public: int data; IntObj(int n) { data=n; } }; Τμ. Πληροφορικής, Α.Π.Θ.

  4. Γενίκευση (genericity) ΙV void main() { Stack genericStack; //εισάγουμε νέα αντικείμενα στη στοίβα genericStack.Push(new IntObj(500)); genericStack.Push(new IntObj(1992)); genericStack.Push(new IntObj(33)); genericStack.Push(new IntObj(1024)); //τυπώνει τα στοιχεία της στοίβας καθώς την αδειάζει: //επειδή η συνάρτηση Pop επιστρέφει δείκτη σε //GenericObject, για να προσπελάσουμε μέλος του //αντικειμένου που βγάλαμε χρειάζεται type casting while(!genericStack.Empty()) cout<<((IntObj*)genericStack.Pop())->data<<endl; } Τμ. Πληροφορικής, Α.Π.Θ.

  5. Γενίκευση (genericity) V template<class T> //stack.h με template class Stack { T data[50]; int nElements; public: Stack() { nElements=0; } void Push(T elem); T Pop(); int Number(); int Empty(); }; #include “stack.h” //stack.cpp template<class T> void Stack<T>::Push(T elem) { data[nElements]=elem; nElements++; } template<class T> T Stack<T>::Pop() { nElements--; return data[nElements];} template<class T> int Stack<T>::Number() { return nElements;} template<class T> int Stack<T>::Empty() { return (nElements==0); } Τμ. Πληροφορικής, Α.Π.Θ.

  6. Γενίκευση (genericity) VI #include <iostream.h> //sta_use.cpp #include “stack.cpp” void main() { Stack <int> intStack; //εισάγουμε νέα αντικείμενα στη στοίβα intStack.Push(500); intStack.Push(1992); intStack.Push(33); intStack.Push(1024); while(!intStack.Empty()) cout<<intStack.Pop())<<endl; } Τμ. Πληροφορικής, Α.Π.Θ.

  7. Γενίκευση (genericity) VII //template συναρτήσεις template <class T> T min(T a, T b) { if(a<b) return a; else return b; } void main() { char c1=‘W’,c2=‘h’; int n1=23,n2=67; long n3=10000; float n4=34.23,n5=7.77; min(c1,c2); min(n1,n2); min(c1,n1); //ΛΑΘΟΣ min(n2,n3); //ΛΑΘΟΣ min(n3,n4); //ΛΑΘΟΣ min(n4,n5); } Τμ. Πληροφορικής, Α.Π.Θ.

  8. Έλεγχος τύπου σε χρόνο εκτέλεσης Είναι δυνατό σε χρόνο εκτέλεσης να διαπιστώσουμε αν ένας δείκτης σε βασική κλάση δείχνει σε αντικείμενο παράγωγης κλάσης. Η C++(νεότερες εκδόσεις)παρέχει τον τελεστή typeid. Για να χρησιμοποιηθεί ο τελεστής πρέπει η βασική κλάση να περιέχει τουλάχιστο μία virtual συνάρτηση. class Shape { public: virtual void plot(GraphicsContext& gc)=0; //. . . } Shape* s; if (typeid(s) == typeid(Rectangle*)) // ο δείκτης s δείχνει σε αντικείμενο Rectangle else // ο δείκτης s δείχνει σε αντικείμενο άλλης κλάσης Τμ. Πληροφορικής, Α.Π.Θ.

  9. Έλεγχος τύπου και downcasting Ι Υπάρχουν περιπτώσεις που οι virtual συναρτήσεις δεν είναι αρκετά ευέλικτες και χρειάζεται έλεγχος τύπου σε χρόνο εκτέλεσης. Θεωρείστε για παράδειγμα τον υπολογισμό της τομής δύο γεωμετρικών σχημάτων που μπορεί να είναι παραλληλόγραμμα ή πολύγωνα. Στη γενική περίπτωση η τομή είναι μία ένωση πολυγώνων, αλλά από την άλλη η τομή δύο παραλληλόγραμμων είναι επίσης παραλληλόγραμμο. Σε αυτή την περίπτωση χρειάζεται να γνωρίζουμε αν ο δείκτης Shape δείχνει σε ένα Rectangle ή αν δείχνει σε αντικείμενο κλάσης που παράγεται από ένα Rectangle. Αν ο έλεγχος επιτύχει θέλουμε να μετατρέψουμε το δείκτη Shape* σε δείκτη Rectangle*, ώστε να αποκτήσουμε πρόσβαση στα μέλη (συναρτήσεις & δεδομένα) του παραλληλόγραμμου. Τμ. Πληροφορικής, Α.Π.Θ.

  10. Έλεγχος τύπου και downcasting ΙΙ Για να χρησιμοποιηθεί ο τελεστής πρέπει η βασική κλάση να περιέχει τουλάχιστο μία virtual συνάρτηση.Ο τελεστής εκτελεί και τον έλεγχο αλλά και τη μετατροπή τύπου. class Shape { public: virtual void plot(GraphicsContext& gc)=0; //. . . } Shape* s; Rectangle* r = dynamic_cast<Rectangle*>(s); if (r != 0) // or είναι ίσος με το s και δείχνει σε αντικείμενο Rectangle else // ο δείκτης s δείχνει σε αντικείμενο που δεν είναι Rectangle Τμ. Πληροφορικής, Α.Π.Θ.

  11. Η εσωτερική παράμετρος μιας συνάρτησης μέλους Date advance(int n) { //προσέθεσε n ημέρες στην ημερομηνία return (*this); } Date add_days(long n) { Date b=(*this); b.advance(n); return b; } το αντικείμενο για το οποίο καλείται η συνάρτηση Τμ. Πληροφορικής, Α.Π.Θ.

  12. Πότε δύο αντικείμενα είναι ίσα; Ι έχουν τις ίδιες τιμές; int m, n; // . . . if (m == n) . . . δείχνουν στις ίδιες τιμές; int* p; int* q; // . . . if (*p == *q) . . . είναι οι ίδιοι δείκτες (αλλάζοντας τον ένα αλλάζει και ο άλλος); int* p; int* q; // . . . if (p == q) . . . Τμ. Πληροφορικής, Α.Π.Θ.

  13. Πότε δύο αντικείμενα είναι ίσα; ΙΙ σύγκριση τιμών αναφορών void f(int& r, int& s) { if (r == s) . . . } είναι οιίδιες αναφορές; (σύγκριση διευθύνσεων μνήμης) if (&r == &s) πότε δύο αντικείμενα είναι ίσα; bool Point::is_equal(Point& b) { return x == b.x && y == b.y; } bool Rectangle::is_equal(Rectangle& b) { return left_top().is_equal(b.left_top()) && right_bottom().is_equal(b.right_bottom()); } Τμ. Πληροφορικής, Α.Π.Θ.

  14. Πότε δύο αντικείμενα είναι ίσα; ΙΙI Θα πρέπει πάντα η ισότητα μεταξύ αντικειμένων να ελέγχεται από κώδικα (συνάρτηση ή τελεστή) που θα γράφει ο προγραμματιστής. ΠΡΟΒΛΗΜΑ Rectnagle* p; Rectangle* q; // . . . if (p == q) . . . ή για έλεγχο αν οι δείκτες αναφέρονται στην ίδια τιμή if ((*p).is_equal(*q)) . . . Τι γίνεται αν ο δείκτης q δείχνει σε FilledRect και ο p σε Rectangle; Τμ. Πληροφορικής, Α.Π.Θ.

  15. Πότε δύο αντικείμενα είναι ίσα; ΙV Θα μπορούσαμε να κάνουμε την is_equalvirtual συνάρτηση, αλλά οι virtual συναρτήσεις επιλέγουν κώδικα ανάλογα με τον τύπο της εσωτερικής παραμέτρου. Στην περίπτωση αυτή μπορεί να αλλάζουν οι τύποι και των δύο παραμέτρων της συνάρτησης. Εδώ χρειάζεται ο τελεστής typeid. bool Rectangle::is_equal(Rectangle& b) { if (typeid((*this)) != typeid(b)) return FALSE; return left_top().is_equal(b.left_top()) && right_bottom().is_equal(b.right_bottom()); } Τμ. Πληροφορικής, Α.Π.Θ.

  16. Δημιουργία αρχείου Ι Δημιουργία και η επικοινωνία με ένα αρχείο: • επίπεδο standard Input/Output (I/O) – για τον προγραμματιστή εφαρμογών • επίπεδο Ι/Ο συστήματος (system level I/O) Στη C++, η είσοδος/έξοδος δεδομένων συνδέεται με το χειρισμό των αποκαλούμενων ροών δεδομένων (streams). Κάθε περίπτωση ροής (αντικείμενο) αντιπροσωπεύει, είτε ένα συγκεκριμένο αρχείο δίσκου, είτε την οθόνη ή το πληκτρολόγιο. Αρχείο επικεφαλίδας <iostream.h> για είσοδο δεδομένων από το πληκτρολόγιο (cin) ή έξοδο στην οθόνη (cout) Το συγκεκριμένο αρχείο – επικεφαλίδας ουσιαστικά περιέχει τον ορισμό της κλάσης iostream τα μέλη της οποίας χρησιμοποιούμε για την είσοδο – έξοδο από και προς τις τυπικές μονάδες εισόδου – εξόδου. Τμ. Πληροφορικής, Α.Π.Θ.

  17. Δημιουργία αρχείου ΙΙ Αρχείο επικεφαλίδας <fstream.h> για είσοδο - έξοδο από και προς αρχείο δίσκου (). Περιέχει την κλάση fstream. H κλάση fstream κληρονομεί τόσο από την iostream, όσο και από την υπερκλάση ios, ενώ η iostream κληρονομεί μέσω των istream και ostream, μόνο από την ios. Συχνά επίσης γίνεται χρήση των κλάσεων ifstream και ofstream, που δηλώνονται στο <fstream.h>, αποκλειστικά για είσοδο ή αντίστοιχα έξοδο δεδομένων σε αρχείο. Στο παράδειγμα που ακολουθεί προηγείται η δήλωση ενός αντικειμένου ροής εξόδου (αρχείο με το όνομα arxs.txt) με το συμβολικό όνομα my_o_file. Τμ. Πληροφορικής, Α.Π.Θ.

  18. Δημιουργία αρχείου και εγγραφή Ι #include <fstream.h> main() { ofstream my_o_file("arxs.txt"); char name[20]="StringArray"; my_o_file<<'A'<<endl; my_o_file<<'a'<<endl; my_o_file<<"The name of the array:” <<endl <<name<<endl; } ΠΕΡΙΕΧΟΜΕΝΑ ΑΡΧΕΙΟΥ arxs.txt: A a The name of the array is: StringArray Τμ. Πληροφορικής, Α.Π.Θ.

  19. Δημιουργία αρχείου και εγγραφή ΙΙ #include <fstream.h> #include <iostream.h> main() { const int NO_OF_CHARS=80; char buffer[NO_OF_CHARS]; ifstream my_i_file("arxs.txt"); while(my_i_file) { my_i_file.getline(buffer, NO_OF_CHARS); cout<<buffer<<endl; } } istream::getline getline(buf,num,delim) όπου: buf = μεταβλητή συμβολοσειράς που χρησιμοποιείται ως περιοχή προσωρινής αποθήκευσης num = μεταβλητή int που δηλώνει το μέγιστο αριθμό χαρακτήρων, που μπορεί να τοποθετηθούν στηνπεριοχή προσωρινής αποθήκευσης Delim= προαιρετική παράμετρος χαρακτήρα η ανίχνευση του οποίουολοκληρώνει την ανάγνωση(προεπιλεγμένη τιμή “\n”) Το σήμα EOF είναι μία από τις συνθήκες λάθους που μπορεί να επιστρέψει μία ροή εισόδου και σημαίνει τέλος αρχείου Τμ. Πληροφορικής, Α.Π.Θ.

  20. Δημιουργία αρχείου και εγγραφή ΙΙΙ fstream::open open(MyFileName, mode, protection) MyFileName = το όνομα του αρχείου mode = μία ή περισσότερες σημαίες ios που συνδυάζονται με | ios::appάνοιγμα για εγγραφή στο τέλος του αρχείου (append) ios::ate άνοιγμα και τοποθέτηση του δείκτη αρχείου στο τέλος ios::in άνοιγμα για ανάγνωση ios::out άνοιγμα για εγγραφή ios::truncαν το αρχείο ήδη υπάρχει, τότε καταστρέφονται τα περιεχόμενά του ios::nocreate αν το αρχείο δεν υπάρχει, τότε η open δεν εκτελείται ios::noreplace αν το αρχείο υπάρχει, τότε η open δεν εκτελείται ios::binaryανοίγει το αρχείο για εγγραφή δυαδικών δεδομένων protection = μία ή περισσότερες σημαίες, που συνδυάζονται με || για τον ορισμό του τύπου πρόσβασης στη ροή filebuf::sh_noneαποκλειστική πρόσβαση (μη διαμοιράσιμο αρχείο) filebuf::sh_read επιτρέπεται η πολλαπλή πρόσβαση για ανάγνωση filebuf::sh_write επιτρέπεται η πολλαπλή πρόσβαση για εγγραφή Τμ. Πληροφορικής, Α.Π.Θ.

  21. Δημιουργία αρχείου και εγγραφή ΙV #include <fstream.h> main() { fstream my_o_file; char name[20]="StringArray"; my_o_file.open("arxs.txt", ios::out | ios::noreplace); my_o_file<<'B'<<endl; my_o_file<<'b'<<endl; my_o_file<<"The name of the array:“ <<endl <<name<<endl; } fstream::close close() Τμ. Πληροφορικής, Α.Π.Θ.

  22. Ανάγνωση - εγγραφή χαρακτήρων Ι istream::get get(inch) όπου: inch =όνομα μεταβλητής χαρακτήρα, στην οποία αποθηκεύεται ο χαρακτήρας που διαβάζεται ostream::put put(outch) όπου: outch = μεταβλητή ή σταθερά χαρακτήρα που η τιμή τηςεγγράφεται στη ροή που καλεί τη συνάρτηση Τμ. Πληροφορικής, Α.Π.Θ.

  23. Ανάγνωση - εγγραφή χαρακτήρων ΙΙ #include <fstream.h> #include <iostream.h> #include <stdlib.h> main(){ ifstream my_i_file; char filename[12]; char in_char; cout<<"Doste onoma arxeiou: "; cin>>filename; my_i_file.open(filename,ios::in); if (!my_i_file) { cout<<"This file does not exist!\n"; exit(0);} while (my_i_file.get(in_char)) { cout << in_char; } my_i_file.close(); } Τμ. Πληροφορικής, Α.Π.Θ.

  24. Ανάγνωση - εγγραφή χαρακτήρων ΙΙΙ #include <fstream.h> #include <iostream.h> #include <stdlib.h> main(){ ifstream my_i_file; ofstream my_o_file; char in_filename[12]; char out_filename[12]; char in_char; cout << “Arxeio pouantigrafetai?"; cin >> in_filename; cout << “Arxeioopou thaantigrafei "; cout << "to " << in_filename << "?" << endl; cin >> out_filename; my_i_file.open(in_filename, ios::in); if (!my_i_file){ cout <<“Arxeio "<< in_filename << " den iparxei!\n"; exit(0);} my_o_file.open(out_filename, ios::out); if (!my_o_file){ cout<<"Lathos sto anoigma" << out_filename << "!\n"; exit(0);} cout << "Antigrafiarxeiou.\n"; while (my_i_file.get(in_char)) {my_o_file.put(in_char); } cout<<"\nArxeioantigrafike\n"; my_i_file.close(); my_o_file.close(); } Τμ. Πληροφορικής, Α.Π.Θ.

  25. Εγγραφήομάδας (block)δεδομένων Ι istream::read read(indata,num) indata = block δεδομένων που διαβάζεται ωςσυμβολοσειρά (char*) αλλά αποδίδεται στηδιεύθυνση μεταβλητής ή αντικειμένου με τον τελεστή & num = ακέραιος που δηλώνει τον αριθμό των bytes που θα διαβάσει η read ostream::write write(outdata,num) όπου: outdata = block δεδομένων που εγγράφεται στη ροή ως char* num = ακέραιος που δηλώνει τον αριθμό των bytes που εγγράφει η write ios::eof eof() επιστρέφει ως αποτέλεσμα μη μηδενική ακέραια τιμή όταν διαβάζεται τέλους αρχείου (EOF) Τμ. Πληροφορικής, Α.Π.Θ.

  26. Εγγραφήομάδας (block)δεδομένων ΙΙ Όταν τα δεδομένα εγγράφονται από την κεντρική μνήμη στη ροή ως έχουν (δηλ. στη δυαδική τους μορφή), τότε το περιεχόμενο του αρχείου είναι σε δυαδική μορφή και μιλάμε για δυαδικό αρχείο. Παράδειγμα εγγραφής δυαδικών δεδομένων . . . Τμ. Πληροφορικής, Α.Π.Θ.

  27. Εγγραφήομάδας (block)δεδομένων ΙΙΙ #include <fstream.h> #include <iostream.h> #include <stdlib.h> class Date {protected: int day; int month; int year; public: void getDate(){ cout<<"\nDoste imera: "; cin>>day; cout<<"\nDoste mina: "; cin>>month; cout<<"\nDoste etos: "; cin>>year;} void printDate(){ cout<<"\nDiavastike imerominia: " <<day<<"-"<<month<<"-" <<year<<endl;} }; main(){ char input,filename[12]; ofstream d_o_file; ifstream d_i_file; Date date1,date2; cout<< "Dose onoma arxeiou? "; cin>> filename; d_o_file.open(filename, ios::out|ios::binary); if (!d_o_file){ cout<<“Arxeio " << filename <<" den iparxei!\n"; exit(0);} cout<<"\nTha eisagete ime/nia (n/o)? "; cin >> input; if (input=='n') { date1.getDate(); d_o_file.write((char*)&date1, sizeof(date1));} Τμ. Πληροφορικής, Α.Π.Θ.

  28. Εγγραφήομάδας (block)δεδομένων ΙV . . . συνέχεια παραδείγματος d_o_file.close(); d_i_file.open(filename,ios::in|ios::binary); d_i_file.read((char *) &date2, sizeof(date2)); if (!d_i_file.eof()) { date2.printDate(); } else { cout<<"Empty file!!\n"; } d_i_file.close(); } Τμ. Πληροφορικής, Α.Π.Θ.

  29. Σειριακή και άμεση προσπέλαση Ι Στη σειριακή εγγραφή, κάθε φορά που εκτελείται μια write, η εγγραφή των δεδομένων γίνεται στις αμέσως επόμενες θέσεις. Αντίστοιχα, κάθε φορά που εκτελείται μια read διαβάζουμε τα δεδομένα που βρίσκονται στις επόμενες θέσεις. Aν π.χ θέλουμε να διαβάσουμε το 5ο record, θα πρέπει να διαβάσουμε πρώτα τα τέσσερα που προηγούνται και στη συνέχεια το 5ο. Αντίθετα, με τυχαία ή άμεση προσπέλαση μπορούμε να διαβάσουμε ή να γράψουμε ένα record, ενδιάμεσα στο αρχείο, με μία μόνο ανάγνωση/εγγραφή. Για να επιτευχθεί αυτό θα πρέπει να γίνει διαχείριση των δεικτών θέσης του αρχείου με κατάλληλο τρόπο. Τμ. Πληροφορικής, Α.Π.Θ.

  30. Σειριακή και άμεση προσπέλαση ΙΙ Το σύστημα εισόδου – εξόδου της C++ διαχειρίζεται δύο δείκτες θέσης (πρόκειται ουσιαστικά για ακεραίους αριθμούς), για κάθε αρχείο: ο δείκτης θέσης ανάγνωσης (get pointer) καθορίζει τη θέση (σε πιο byte), από την οποία θα γίνει η επόμενη ανάγνωση ο δείκτης θέσης εγγραφής (put pointer) καθορίζει τη θέση, στην οποία θα γίνει η επόμενη εγγραφή Όταν ένα αρχείο ανοίγει (συνάρτηση open) τότε οι δείκτες θέσης τοποθετούνται στην αρχή του αρχείου (η αρίθμηση των bytes αρχίζει από το μηδέν). Κάθε φορά που εκτελείται μια συνάρτηση ανάγνωσης (όπως read, get κ.λ.π.) ο δείκτης θέσης ανάγνωσης μετακινείται αυτόματα στη θέση εκείνη από όπου θα γίνει η επόμενη ανάγνωση. Επίσης, κάθε φορά που εκτελείται μια συνάρτηση εγγραφής ο δείκτης θέσης εγγραφής μετακινείται αυτόματα στη θέση εκείνη, όπου θα γίνει η επόμενη εγγραφή. Τμ. Πληροφορικής, Α.Π.Θ.

  31. Σειριακή και άμεση προσπέλαση ΙΙΙ istream::tellg tellg() επιστρέφει μία τιμή long που δηλώνει τη θέση στην οποία βρίσκεται ο δείκτης ανάγνωσης της ροής εισόδου οstream::tellp tellp() επιστρέφει μία τιμή long που δηλώνει τη θέση στην οποία βρίσκεται ο δείκτης εγγραφής της ροής εξόδου Τμ. Πληροφορικής, Α.Π.Θ.

  32. Σειριακή και άμεση προσπέλαση ΙV istream::seekg seekg(offset,refmark) Το offset εκφράζει το πλήθος των bytes, που πρέπει να μετακινηθεί ο δείκτης θέσης, ως προς το επιθυμητό σημείο αναφοράς refmark. Το refmark ορίζει την τιμή του σημείου αναφοράς: ios::beg αρχή του αρχείου (προκαθορισμένη τιμή) ios::curτρέχουσα θέση του αρχείου ios::end τέλος του αρχείου οstream::seekp seekp(offset,refmark) όπως και η προηγούμενη συνάρτηση, για το δείκτη θέσης εγγραφής Τμ. Πληροφορικής, Α.Π.Θ.

  33. Παράδειγμα σειριακής εγγραφής #include <iostream.h> #include <fstream.h> class person {protected: char name[40]; int age; public: void getData(){ cout<<"\n Dwste Onoma:"; cin>>name; cout<<"Dwste Hlikia:"; cin >> age; } void showData(){ cout<<"\n Onoma:"<<name; cout<<"\n Hlikia:"<<age<<"\n"; } }; main(){ char ch; person pers;  fstream file; file.open("PERSON.DAT", ios::app); cout<<"\nEisagete eggrafi: "; do{ pers.getData(); file.write((char*)&pers, sizeof(pers)); cout<<«Sinexizete?(y/n)"; cin>>ch; } while (ch=='y'); file.close(); file.open("PERSON.DAT", ios::in); file.read((char*)&pers, sizeof(pers)); while (!file.eof()){ pers.showData(); file.read((char*)&pers, sizeof(pers));} } Τμ. Πληροφορικής, Α.Π.Θ.

  34. Παράδειγμα άμεσης προσπέλασης #include <iostream.h> #include <fstream.h> class person {protected: char name[40]; int age; public: void getData(){ cout<<"\n Dwste Onoma:"; cin>>name; cout<<"Dwste Hlikia:"; cin >> age; } void showData(){ cout<<"\n Onoma:"<<name; cout<<"\n Hlikia:"<<age<<"\n"; } }; main(){ char ch; person pers;  ifstream file; file.open("PERSON.DAT"); file.seekg(0,ios::end); int endposition=file.tellg(); int n=endposition/ sizeof(person); cout<<"\nYparxoun "<<n <<" eggrafes sto arxeio"; cout<<"\nDoste ti thesi eggrafis pou anazeitate:"; cin>>n; int position=(n-1)* sizeof(person); file.seekg(position); file.read((char*)&pers, sizeof(pers)); pers.showData(); file.close(); } Τμ. Πληροφορικής, Α.Π.Θ.

  35. Χρήσιμες συναρτήσεις Ι ios::bad bad() Επιστρέφει ως αποτέλεσμα μη μηδενική ακέραια τιμή όταν ανιχνεύεται λάθος ανάγνωσης-εγγραφής. Στην περίπτωση αυτή δεν πρέπει να συνεχισθεί η ανάγνωση-εγγραφή από τη ροή. ios::fail fail() Επιστρέφει ως αποτέλεσμα μη μηδενική ακέραια τιμή όταν ανιχνεύεται λάθος ανάγνωσης – εγγραφής, εκτός του EOF. Αν το λάθος είναι ανανήψιμο, τότε η ανάγνωση – εγγραφή μπορεί να συνεχισθεί, αφού προηγουμένως κληθεί η clear() για επαναφορά των σημαιών λάθους στην προκαθορισμένη κατάσταση. ios::good good() Επιστρέφει μη μηδενική τιμή, όταν όλες οι σημαίες λάθους βρίσκονται στην προκαθορισμένη κατάσταση (δεν υπάρχει λάθος). Τμ. Πληροφορικής, Α.Π.Θ.

  36. Χρήσιμες συναρτήσεις ΙΙ ios::clear clear() Επαναφέρει τις σημαίες λάθους στην προκαθορισμένη κατάσταση. istream::ignore ignore(num,delim) Αγνοεί τα επόμενα num bytes της ροής εκτός και αν πριν συμπληρωθεί ο αριθμός τους εντοπισθεί ο χαρακτήρας delim. Αν δε δοθεί τιμή στην παράμετρο num, τότε αγνοείται ένας μόνο χαρακτήρας, ενώ η προκαθορισμένη τιμή για την παράμετρο delim είναι το EOF. istream::peek peek() Επιστρέφει τον επόμενο χαρακτήρα με τη μορφή ακέραιης τιμής, χωρίς όμως να τον αφαιρεί από τη ροή. istream::putback putback(inch) Επανατοποθετεί στη ροή εισόδου το χαρακτήρα inch που διαβάσθηκε τελευταία. Αν αντί γι΄ αυτόν επιχειρηθεί η τοποθέτηση άλλου χαρακτήρα, τότε το αποτέλεσμα της συνάρτησης είναι απροσδιόριστο. Τμ. Πληροφορικής, Α.Π.Θ.

More Related