Η συνάρτηση main θα ορίζει την μεταβλητή τύπου LineFile με την οποία γίνεται όλη η δουλειά. Κατόπιν θα κατανέμει την κάθε επιλογή του χρήστη σε μία κατάλληλη συνάρτηση-μέλος της κλάσης η οποία θα αναλαμβάνει την διεκπεραίωση της επιλογής του χρήστη. Μετά την διεκπεραίωση της εργασίας, θα επανεμφανίζεται το μενού επιλογής. Τέλος της εργασίας του προγράμματος θα γίνεται με πληκτρολόγιση του γράμματος q. Οι άλλες επιλογές θα αντιστοιχούν σε άλλα γράμματα. Η μορφή της main να είναι η εξής:
int main(int argc, char* argv[]) { LineFile lf("kat.txt"); lf.TimeString(); char ch(1); while( ch != 'q' ) { ch = lf.MenuSelection(); switch(ch) { case 'a': lf.AppendLine(); break; case 'd': lf.DeleteLine(); break; case 'p': lf.PrintLines(); break; case 'r': lf.ReplaceLine(); break; case 's': lf.ShowLine(); break; case 'f': lf.NewWordSearch(); break; case 'g': lf.OldWordSearch(); break; case 'q': //exit break; default: cout << "Error, please type only one of: a, d, p, r, s, f, g and q = quit" << endl; break; } } }
LineFile lf("kat.txt"); | Ο κατασκευαστής ο οποίος ορίζει την μεταβλητή lf τύπου LineFile και δίδει στην fName μεταβλητή της κλάσης το όνομα του αρχείου kat.txt στο οποίο καταχωρούνται οι γραμμές. |
lf.TimeString(); lf.MenuSelection(); lf.AppendLine(); lf.DeleteLine(); lf.PrintLines(); lf.ReplaceLine(); lf.ShowLine(); lf.NewWordSearch(); lf.OldWordSearch(); | 9 συναρτήσεις που κάνουν τις κύριες εργασίες του προγράμματος. Μετά τον ορισμό της μεταβλητής lf ξεκινά ένας κύκλος επαναλαμβανόμενος κατά τον οποίον ο χρήστης καθορίζει την εργασία τυπώνοντας έναν χαρακτήρα. Η παραπομπή από τον χαρακτήρα στην αντίστοιχη συνάρτηση που εκτελεί την εργασία γίνεται από την εντολή switch. Αυτή παίζει το ρόλο ενός διακόπτη-κατανεμητή. Τα ονόματα των συναρτήσεων είναι δηλωτικά των εργασιών που επιτελούν. |
ch = lf.MenuSelection(); switch(ch) { case 'a': ............ case 'g': lf.OldWordSearch(); break; case 'q': //exit break; default: cout << "Error ... break; } | Απόσπασμα κώδικα του κατανεμητή switch. Η συνάρτηση ch = lf.MenuSelection(); παίρνει από τον χρήστη έναν χαρακτήρα. Οταν ο χαρακτήρας είναι a τότε καλείται η συνάρτηση lf.AppendLine() με την οποία ο χρήστης τυπώνει και καταχωρεί στο αρχείο μιά νέα γραμμή δεδομένων. Ανάλογες εργασίες γίνονται όταν η μεταβλητή ch έχει τις τιμές d, p, r, s, f, p, q . Ειδικά με την τελευταία τιμή q ο χρήστης διακόπτει την λειτουργία του while και τερματίζει το πρόγραμμα. Το απόκομμα του switch που ξεκινά με το default εκτελείται στην περίπτωση που ο χρήστης δώσει έναν χαρακτήρα διαφορετικό από τους προηγουμένους 8. Σ αυτήν την περίπτωση τυπώνεται ένα μήνυμα λάθους. |
char LineFile::MenuSelection() { WriteMessage("<MENU>\n AddLine (a) , DeleteLine (d) , PrintLines (p) , ReplaceLine (r)"); WriteMessage(" ShowLine (s) , WordSearch (f) , AgainSearch (g) , Quit (q)"); WriteMessage("</MENU>"); cin.getline(line,MXCH); // eat all the line but use only 1st char if( GetLineLength() >10 ) // append !! *** user forgot to press a before !! { AppendLineEndFile(); } return line[0]; }Η συνάρτηση-μέλος της κλάσης LineFile χρησιμοποιεί μιά άλλη συνάρτηση-μέλος της κλάσης, την WriteMessage μέσω της οποίας γράφει (το παραπάνω) κείμενο στην κονσόλα οθόνης του χρήστη. Εδώ βλέπουμε ότι τυπώνει μερικές γραμμές που καθοδηγούν τον χρήστη στο τί ακριβώς νά κάνει. Συγκεκριμένα τον προτρέπουν να πληκτρολογήσει ένα από τα γράμματα a, d, p, r, s, f, g, q . Κατόπιν η συνάρτηση διαβάζει (μέσω της cin >> ch ;) την επιλογή του χρήστη και επιστρέφει τον χαρακτήρα που διάβασε.
int LineFile::GetLineLength() { return strlen(line);}Η συνάρτηση strlen βρίσκει το πλήθος των χαρακτήρων μιάς char* μεταβλητής.
void LineFile::WriteMessage( char* mess ) { cout << mess << endl; }Το ίδιο και η συνάρτηση:
void LineFile::AppendLineEndFile() { fstream kata(fName, ios::app); // open to append WriteLine( kata ); kata.close(); }Τούτη ανοίγει το αρχείο fName και γράφει στο τέλος του τα περιεχόμενα της line. Τέλος η WriteLine κάνει πράγματι την εγγραφή αφού προσθέσει στο τέλος της γραμμής την σφραγίδα (myTime) με την ημερομηνία:
void LineFile::WriteLine( fstream & kata ) { kata << line << setw(MAIN_LINE_WIDTH-GetLineLength()) << myTime << setw(MARGIN) << "**\n"; }Το απόσπασμα κώδικα
if( GetLineLength() >10 ) // append !! *** user forgot to press a before !! { AppendLineEndFile(); }το τοποθέτησα μετά από δοκιμές του προγράμματος. Παρατήρησα ότι όταν ήθελα να καταχωρήσω μιά γραμμή, έπρεπε ΠΡΩΤΑ να δώσω το γράμμα a και κατόπιν να πληκτρολογήσω το κείμενο. Ξεχνούσα λοιπόν να δώσω πρώτα το γράμμα και έγραφα κατ' ευθείαν την γραμμή που ήθελα να καταχωρήσω. Το αποτέλεσμα ήταν να χάνω αυτήν την γραμμή και τον χρόνο μου. Το if λοιπόν εξετάζει το μήκος της line και αν είναι μεγαλύτερο από 10 (η strlen(...) βρίσκει το πλήθος χαρακτήρων ενός char* ) καταχωρεί την πληκτρολογημένη γραμμή στο αρχείο, υποθέτοντας ότι ο χρήστης έκανε το σφάλμα που περιέγραψα. Αν ο χρήστης δώσει ένα μόνο από τα 8 γράμματα και πατήσει το enter το πρόγραμμα λειτουργεί κανονικά.
Βλέπουμε εδώ ένα χαρακτηριστικό στιγμιότυπο της ιεραρχίας των συναρτήσεων. Κάθε μιά τους διασπά
την δουλειά σε άλλες μικρότερες (διαίρει και βασίλευε) και τις παραπέμπει σε άλλες συναρτήσεις
οι οποίες με την σειρά τους διασπούν την δουλειά τους σε άλλες κ.ο.κ. Το πράγμα θυμίζει την
υπαλληλική ιεραρχεία, στην οποία ο διευθυντής αναθέτει στους υποδιευθυντές, αυτοί στους τμηματάρχες
κτλ. κτλ. μέχρι να φτάσει η δουλειά κάτω-κάτω στους τελευταίους υπαλλήλους, που ο καθένας τους
κάνει μιά εντελώς συγκεκριμένη και περιορισμένη εργασία.
void LineFile::TimeString() { time_t long_time; // get time is seconds time( &long_time ); struct tm *newtime; // to format time-info newtime = localtime( &long_time ); // transform to date sprintf(myTime, "%2d/%2d/%2d ", newtime->tm_mday , newtime->tm_mon+1, newtime->tm_year-100 ); }Η συνάρτηση sprintf έχει την ιδια σύνταξη με την printf, μόνο που τυπώνει κείμενο σε διάνυσμα χαρακτήρων (εδώ στο myTime). Έτσι ετοιμάζω κατά κάποιο τρόπο μιά σφραγίδα με την ημερομηνία, με την οποία σφραγίζω κάθε γραμμή που εισάγεται στο αρχείο.
void LineFile::AppendLine( ) { WriteMessage( "write a line") ; // WARNING check length ????? cin.getline(line,MXCH); // get line from cin AppendLineEndFile(); }Η συνάρτηση αυτή κάνει τα εξής:
void LineFile::PrintLines() { int n(0); WriteMessage("-----------"); ifstream kata; // open file to read from kata.open(fName); while( kata.getline( line, MXCH ) ) { cout << line << endl; n++; } WriteMessage("-----------"); cout << n << " lines in " << fName << endl; }Η συνάρτηση αυτή τυπώνει στην κονσόλα όλες τις γραμμές του αρχείου μέσω ενός while που λειτουργεί όσο υπάρχει η δυνατότητα ανάγνωσης μιάς ακόμη γραμμής από το αρχείο μας. Με τις εντολές ifstream kata; kata.open(fName); ανοίγουμε το αρχείο μας για ανάγνωση. Η εντολή kata.getline( line, MXCH ) διαβάζει διαδοχικές γραμμές από το αρχείο μας και επιστρέφει το πραγματικό μήκος της γραμμής ή 0 όταν φτάσει στο τέλος του αρχείου. Τότε ακριβώς διακόπτεται το while .Τα υπόλοιπα τα έχουμε ξαναδεί.
void LineFile::ReplaceLine( ) { int n = AcceptDelete(); // ask user etc... if(n == 0) return; // user canceled WriteMessage("Write new line"); cin.getline(line,MXCH); // get line from user fstream kata; OpenSeekLine(kata, n, false ); // false = to write WriteLine( kata ); kata.close(); }Η πρώτη εντολή n = AcceptDelete(); προτρέπει τον χρήστη να δώσει έναν ακέραιο που αντιστοιχεί στην γραμμή την οποία θέλει να αλλάξει. Η συνάρτηση αυτή πρίν επιστρέψει τον ακέραιο που έδωσε ο χρήστης, ξαναρωτά αν όντως θέλει να αντικαταστήσει την ν-στη γραμμή. Ο χρήστης πρέπει να πατήσει y (=yes), αν μετανοιώσει και θέλει να κρατήσει την παλιά γραμμή, πατά ένα άλλο γραμμα και η συνάρτηση n = AcceptDelete(); επιστρέφει το 0.
OpenSeekLine(kata, n, false ); // false = to writeανοίγει το αρχείο μας γιά ανάγνωση+εγγραφή και τοποθετεί τον δείκτη στην αρχή της n-στής γραμμής (που θέλουμε να αλλάξουμε). Κατόπιν η συνάρτηση WriteLine(kata); γράφει το περιεχόμενο της line στην n-γραμμή του αρχείο (σβύνοντας την παλιά). Η συνάρτηση
void LineFile::OpenSeekLine( fstream & kata, int count, bool toRead /*true*/ ) { fstream::pos_type pos((count-1)*TOTAL_WIDTH); kata.open(fName, ios::in | ios::out ); // WARNING errors ?? if(toRead) kata.seekg(pos); else kata.seekp(pos); }ανοίγει ένα αρχείο για ανάγνωση+εγγραφή και τοποθετεί τον δείκτη στην αρχή της count-γραμμής. όταν η toRead αληθεύει τότε πρόκειται γιά ανάγνωση, αλλοιώς γιά εγγραφή.
int LineFile::GetAnInteger() { int N = NumOfLines(); cout << "Give an integer 0 < n <= " << N << endl; cin.getline(line,MXCH); int n = atoi(line); // transform to int if( (n<=N) && ( n > 0) ) return n; // normal case else if( n <=0 ) return 1; // if <0 replace by 1 else return N; // if > N replace by N }Η συνάρτηση NumOfLines προσδιορίζει το πλήθος γραμμών του αρχείου από το πλήθος όλων των χαρακτήρων που περιέχει, διαιρώντας το με το μήκος γραμμής του:
int LineFile::NumOfLines() { fstream kata(fName, ios::binary | ios_base::in ); kata.seekg(0,ios_base::end); // set ptr to end of file int n ( kata.tellg()/TOTAL_WIDTH); // this is the total line-nr kata.close(); return n; }Εδώ όλη δουλειά γίνεται με συναρτήσεις της fstream. Η τιμή της kata.tellg() είναι το πλήθος όλων των χαρακτήρων του αρχείου. TOTAL_WIDTH είναι το μήκος γραμμής του αρχείου.
void LineFile::ShowLine( ) { int n = GetAnInteger(); GetThisLine(n); DisplayNrCommentLine( n , "-line is:" ); }Η συνάρτηση ζητά πάλι από τον χρήστη έναν αριθμό (n = GetAnInteger();) και διαβάζει από το αρχείο μας την αντίστοιχη γραμμή με την συνάρτηση GetThisLine(n);. Κατόπιν τυπώνει το αποτέλεσμα στην κονσόλα. Η τελευταία συνάρτηση:
void LineFile::GetThisLine( int count ) { fstream kata; OpenSeekLine(kata, count); kata.getline( line, MXCH ); kata.close(); }χρησιμοποιεί πάλι την OpenSeekLine για να ανοίξει το αρχείο και να τοποθετηθεί στην αρχή της count-γραμμής προς ανάγνωση. Αντιγράφει κατόπιν την count-στη γραμμή στην line και κλείνει το αρχείο. Η συνάρτηση
void LineFile::DisplayNrCommentLine( int n, char* comment ) { WriteMessage("-----------"); cout << n << comment << endl <<line << endl; WriteMessage("-----------"); }τυπώνει α) τον αριθμό ν της γραμμής, β) ένα μικρό κείμενο (comment) και γ) το περιεχόμενο της line.
void LineFile::NewWordSearch() { wordFound=false; // not found yet wordLineStart=1; // line to start search if( GetWordSearchFor( wordSearch ) ) // is a real word ?? { int lineFound = FindLineWord( wordSearch , wordLineStart); if( lineFound >-1 ) // if some line found { wordFound = true; // prepare for next search ShowLineFound( lineFound ); } else //nothing found cout << "passed end of file" << endl; // inform user that no other line ... } else cout << "no word to search for" << endl; }Η συνάρτηση έχει απλή λογική. Χρησιμοποιεί τρεις μεταβλητές της LineFile που υποβοηθούν το ψάξιμο στις γραμμές:
bool LineFile::GetWordSearchFor( string & str ) { static char seps[] = " ,\t\n"; WriteMessage(" Give a word to search for:"); cin.getline( line, MXCH ); // get a line from user if(strlen(line)==0) return false; // nothing to search for else str = strtok( line, seps ); // its first word (token) return true; }Η πρώτη εντολή της παραπάνω συνάρτησης ορίζει τον ορμαθό χαρακτήρων , \t\n (κενό, κόμα, διάστημα, αλλαγή γραμμής) οι χαρακτήρες αυτοί υποτίθενται ότι χρησιμοποιούνται στο κείμενό μας γιά να χωρίζουμε τις λέξεις. Ο ορμαθός αυτός χρησιμοποιήται στην συνάρτηση (βιβλιοθήκης <string.h>) η οποία βρίσκει τις λέξεις από τις οποίες αποτελείται η line και επιστρέφει κάθε φορά μιά λέξη (μπορεί να εφαρμοσθεί κατ' επανάληψη στην line και να μας δώσει όλες τις λέξεις που την αποτελούν). Η πραγματική αναζήτηση της λέξης στις γραμμές γίνεται στην lineFound = FindLineWord( wordSearch , wordLineStart); που κάνει τα εξής:
int LineFile::FindLineWord( string & word , int lineToStart) { fstream kata; OpenSeekLine( kata, lineToStart ); // open and go to start of <lineToStart> int n(lineToStart); int result; while( kata.getline( line, MXCH ) ) // read line from file { result = (int)WordInLine( word ) ; // test if word there if( result > -1 ){ kata.close(); return n;} n++; } kata.close(); return -1; }Στις πρώτες γραμμές τις η συνάρτηση ανοίγει πάλι το αρχείο και τοποθετεί τον δείκτη στην αρχή της lineToStart γραμμής γιά ανάγνωση. Κατόπιν αρχίζει να διαβάζει γραμμές (while( kata.getline( line, MXCH ) )) και να ψάχνει σε κάθε γραμμή μήπως βρεί την λέξη (result = (int)WordInLine( word ) ;). Μόλις την βρεί επιστρέφει τον αριθμό γραμμής στην οποία βρήκε την λέξη.Αν δεν βρει τίποτε επιστρέφει την τιμή -1.
void LineFile::OldWordSearch() { if( wordFound ) // something has been found previously { int lineFound; if( !(wordLineStart<NumOfLines()) || (lineFound = FindLineWord( wordSearch , wordLineStart+1)) == -1 ) { cout << "passed end of file" << endl; // nothing new found wordLineStart = 1; // to restart search } else { ShowLineFound( lineFound ); } } else NewWordSearch(); // start a new search }Και πάλι την πραγματική δουλειά κάνει η lineFound = FindLineWord( wordSearch , wordLineStart); . Οι άλλες εντολές εξετάζουν απλά τα αποτελέσματα που προκύπτουν απ αυτήν την συνάρτηση.
void LineFile::DeleteLine( ) { unsigned int n = (unsigned int)AcceptDelete(); // ask user etc... if(n == 0 ) return ; // user canceled ... do nothing unsigned int N = NumOfLines(); // find total lines unsigned int totpos = (N-1)*TOTAL_WIDTH; // size after deletion unsigned int beforeSize = (n-1)*TOTAL_WIDTH; // size before line unsigned int afterSize = totpos-beforeSize; // size after line char * pch = new char[ totpos ]; // to receive the new text if(n>1) // if not first line delete PutInBuffer( pch, 0, beforeSize ); // store upper part to buffer if(n != N) // i.e. if not last line to delete PutInBuffer( pch+beforeSize, n*TOTAL_WIDTH, afterSize ); // store lower part to buffer OverideFileWithBuffer( pch, totpos ); // write back buffer to file delete[] pch; // WARNING memory ??? }Η λογική της τελευταίας συνάρτησης είναι η εξής: α) Δημιούργησε ένα χώρο στην μνήμη (pch) όπου θα αποθηκευθεί όλο το κείμενο πλήν της γραμμής n προς αφαίρεση. β) Γράψε σ αυτό τον χώρο στην μνήμη τις Ν-1 προηγούμενες και τις Ν-n επόμενες γραμμές, όπου Ν ο συνολικός αριθμός γραμμών. γ) Ξαναγράψε τις υπόλοιπες γραμμές από τον χώρο μνήμης στο αρχείο. Την εγγραφή στο χώρο μνήμης αναλαμβάνει η συνάρτηση:
void LineFile::PutInBuffer( char* pch, unsigned int offset, unsigned int size ) { fstream kata(fName, ios::binary | ios_base::out | ios_base::in ); kata.seekg(offset); // start here reading from file kata.read( pch, size ); // ... put <size> bytes in pch kata.close(); }Η συνάρτηση
void LineFile::OverideFileWithBuffer( char * pch, unsigned int size ) { ofstream kata(fName, ios::binary | ios_base::trunc ); kata.write( pch, size ); kata.close(); }γράφει το περιεχόμενο του char * pch στο αρχείο. Οι εργασίες αυτές υλοποιούν την αναδιάρθρωση του αρχείου που μικραίνει κατά μία γραμμή. Οι εντολές
char * pch = new char[ totpos ]; delete[] pch;Δεσμεύούν και αποδεσμεύουν αντίστοιχα χώρο από totpos bytes στην μνήμη. Κανονικά θα έπρεπε σε κάθε νέα αίτηση μνήμης με την new να εξετάζουμε αν όντως το αίτημα ικανοποιήται ή όχι. Το θέμα αυτό θα το δούμε στις exceptions που είναι ο μηχανισμός αντιμετώπισης σφαλμάτων της C++.
string a, b, c, d; a = "Omiros"; b = "Platon"; c = a; int n = a.length(); // το n = 6 (πλήθος χαρακτήρων) char myText[20]; string myString(myText); // στο myString αποδίδεται το περιεχόμενο του myText //Στην επόμενη εντολή δημιουργήται πάλι ένα string και αποδίδεται και περιεχόμενο. string myBigString("to be or not to be, that is the question!"); string mySmall("to"); int n = myBigString.find( mySmall ); // ψάχνει να βρει το mySmall στο myBigString //επιστρέφει -1 αν δεν το βρει bool what = mySmall.empty() ); // επιστρέφει true αν το string ειναι άδειο (χωρις κείμενο) char ch = myBigString[11]; // το 11-το γράμμα του const char* string::data(); // μιά συνάρτηση της κλάσης που επιστρέφει την διεύθυνση // του πρώτου χαρακτήρα από τον ορμαθό χαρακτήρων που περιέχει η string. string a, b, c; a += b; // αυτή επεκτείνει το a , προσθέτοντας στο τέλος του όλους τους χαρακτήρες του b a += "some text"; // ανάλογα προς την προηγούμενη a = b + c; // το a περιέχει την συνένωση των χαρακτήρων των δύο ορμαθών
fstream kata ; // ρεύμα ανάγνωσης+εγγραφής χαρακτήρων ifstream ikata; // ρεύμα ανάγνωσης χαρακτήρων ofstream okata; // ρεύμα εγγραφής χαρακτήρων kata.open(fName, ios::app); // σύνδεση ρεύματος με το αρχείο με όνομα fName // προς εγγραφή στο τέλος του αρχείου, ισοδύναμα: fstream kata(fName, ios::app); // ισοδύναμη προς προηγούμενη εντολή ofstream kata(fName, ios::app);// ισοδύναμη προς προηγούμενη εντολή // οι δύο τελευταίες είναι constructors των αντιστοίχων κλάσεων και ανοίγουν το αντίστοιχο // αρχείο αμέσως μετά την κατασκευή του αντικειμένου // η γνωστή μας κονσόλα cout είναι μιά ειδική ostream // (σαν την ofstream χωρίς σύνδεση με αρχείο) // η γνωστή μας κονσόλα cin είναι μιά ειδική istream ikata.getline( buffer, length ); // inctl μπορεί να είναι ifstream ή fstream // buffer είναι διάνυσμα χαρακτήρων (char* ...) και length ο μέγιστος αριθμός // χαρακτήρων προς ανάγνωση okata << myString; // okata είναι fstream ή ofstream okata << buffer; cout << "my name"; // ..οπως ήδη συναντήσαμε ofstream kata(fName, ios::binary | ios_base::trunc ); // σύνδεση με αρχείο fName για εγγραφή δυαδικών δεδομένων (ios::binary) // ενδεχόμενα περιεχόμενα του αρχείου διαγράφονται (ios_base::trunc) kata.write( buffer, length ); // εγγραφή δυαδικών δεδομένων (bytes) απο το buffer kata.read( buffer, length ); // ανάγνωση από το kata στο buffer length bytes kata.close(); // κλείσιμο αρχείου kata.seekg(pos); // τοποθέτηση δείκτη ανάγνωσης (από που ξεκινά επόμενη ανάγνωση) kata.seekp(pos); // τοποθέτηση δείκτη εγγραφής (από που ξεκινά επόμενη εγγραφή) // η πρώτη εντολή μόνο για fstream και ifstream // η δεύτερη μόνο γιά fstream και ofstream kata.seekg( position, ios_base::end); //τοποθέτηση δείκτη ανάγνωσης στην θέση position // μετρώντας από το τέλος του αρχείου totpos = kata.tellg(); // λήψη του δείκτη ανάγνωσης (που αρχίζει επόμενη ανάγνωση) totpos = kata.tellp(); // λήψη του δείκτη εγγραφής // μπορούμε να χρησιμοποιούμε τους τελεστές << και >> γιά όλους τους στανταρτ τύπους // μεταβλητών : int a; char b; unsigned int c; double dbl; float flt; okata << a << b << c << dbl << flt << endl; ikata >> a >> b >> c >> dbl >> flt ; // όλα αυτά είναι flags, συμβολικοί ακέραιοι που καθορίζουν ιδιότητες των streams ios::app // καθορίζει ότι θα γίνει καταχώρηση στο τέλος αρχείου ios::in // ότι το αρχείο είναι γιά εγγραφή ios::out // ότι το αρχείο είναι γιά ανάγνωση ios::trunc // ότι θα διαγραφούν τα παλιά και θα εγγραφούν νέα δεδομένα ios::binary // ότι θα γίνει διαχείριση bytes και όχι χαρακτήρων (κειμένου) // ορισμένες απ' αυτές μπορούν να συνδιασθούν με το λογικό |: (ios::in | ios:: out | ios::binary) // ...διαχείριση bytes για εγγραφή + ανάγνωση
char LineFile::MenuSelection() { ΓράψεΜήνυμαΟθόνη(); ΠάρεΚείμενοΑποΧρήστη(); ΚάνεΕλεγχοΤιΕγραψε(); ΕπίστρεψεΠρώτοΧαρακτήρα(); }ανάλογη ανάλυση όλων των κυρίων συναρτήσεων θα προσδιορίσει τις δευτερεύουσες π.χ.
void LineFile::DeleteLine( ) { ΠάρεΑριθμόΓραμμήςΑπόΧρήστη(); ΠαρουσίασεΓραμμήΠροςΑφαίρεση(); ΠάρεΒεβαίωσηΓιαΣβύσιμο(); ΔιαδικασίαΣβυσίματοςΓραμμής(ν); } void LineFile::ΔιαδικασίαΣβυσίματοςΓραμμής(ν) { ΒρεςΜεροςΑρχειουΠρινΓραμμη(ν); ΒρεςΜέροςΑρχειουΜετάΓραμμή(ν); ΓράψεΤαΔύοΜερηΣτηΜνήμη(); ΣυνένωσεΤα(); ΞαναμετάφερεΣτοΑρχείο(); }