Το αρχείο κεφαλή STDIO.C

Στα προηγούμενα κεφάλαια απλά χρησιμοποιούσαμε τη συνάρτηση printf της 
βιβλιοθήκης βασικών συναρτήσεων εισόδου εξόδου, όπως επίσης και το αρχείο 
κεφαλή STDIO.H. Τώρα είναι καιρός να μελετήσουμε λίγο βαθύτερα τις 
λειτουργίες εισόδου και εξόδου της C. Σε αντίθεση με τις περισσότερες γλώσσες 
η C δεν έχει καθόλου ενσωματωμένες προτάσεις εισόδου εξόδου. Όλες οι 
σχετικές λειτουργίες είναι σε μορφή συναρτήσεων γιά να αυξάνουν τη 
μεταφερτότητα της γλώσσας. Φυσικά ο κάθε νέος προγραμματιστής σε C δεν 
θέλει να ξανα-ανακαλύπτει τον τροχό και γι'  αυτό υπάρχουν οι συναρτήσεις 
βιβλιοθήκης. Η βασική βιβλιοθήκη είναι γραμμένη από τους σχεδιαστές της C, 
τους Kernigan και Ritchie και περιγράφεται αναλυτικά στο βιβλίο τους "Η 
γλώσσα Προγραμματισμού C" ("The C Programming Language"), που υπάρχει 
μεταφρασμένο και στα Ελληνικά και παραμένει πάντα το σημαντικότερο βιβλίο 
αναφοράς στη C.

'Οταν λέμε βασική είσοδος και έξοδος αναφερόμαστε στη διαχείριση των πιό 
συνηθισμένων συσκευών εισόδου και εξόδου, δηλαδή το πλήκτρολόγιο και η 
οθόνη. Επειδή ακριβώς αυτές οι συσκευές είναι τόσο βασικές η C αντί να 
χρησιμοποιεί γενικές συναρτήσεις εισόδου εξόδου και να ονομάζει τις ίδιες 
συσκευές συνεχώς έχει μιά ομάδα συναρτήσεων που αφορούν ειδικά στη χρήση 
πλήκτρολογίου και οθόνης. Όταν θα προχωρήσουμε στη διαχείριση αρχείων και 
γενικότερων συσκευών θα δούμε οτι εκεί υπάρχει ένα αντίστοιχο 'υπερσύνολο' 
συναρτήσεων όπου μπορούμε να ονομάσουμε το αρχείο ή τη συσκευή εισόδο ή/και 
εξόδου.

Το πρόγραμμα του αρχείου SIMPLEIO.C θα αποτελέσει το πρώτο μας 
παράδειγμα.                                     

Το πρώτο σημείο που πρέπει να τονίσουμε είναι το αρχείο κεφαλή STDIO.H. Η 
λειτουργία του και η σημασία του έχουν εξηγηθεί στο κεφάλαιο το σχετικό με 
τις βιβλιοθήκες συναρτήσεων. Κάτι που δεν είπαμε τότε σχετικά με την εντολή 

#include είναι οτι η γενική σύναταξη της εντολής επιτρέπει δύο μορφές:

#include <όνομα αρχείου κεφαλής>  ή  #include "όνομα αρχείου κεφαλής"

Η διαφορά έγκειται στο γεγονός οτι η σύνταξη με τα < > σημαίνει ότι ο 
μεταφραστής και ο συνδετής θα αναζητήσουν το αρχείο κεφαλή πρώτα στον 
ειδικό κατάλογο include (include directory) του συστήματος. Η σύνταξη με τα " 
"  σημαίνει οτι το αρχείο κεφαλή θα αναζητηθεί πρώτα στον τρέχοντα κατάλογο 
και στη συνέχεια στον κατάλογο include.

Στη συνέχεια του προγράμματος έχουμε τη δήλωση μιάς μεταβλητής χαρακτήρα 
με όνομα c. Η πρώτη εκτελέσιμη πρόταση είναι η κλήση της συνάρτσηςη printf 
γιά την εφάνιση ενός μηνύματος. Το μήνυμα αυτό προτρέπει τον χρήστη να 
εισάγει χαρακτήρες από το πλήκτρολόγιο τερματίζοντας το πρόγραμμα με την 
εισαγωγή του χαρακτήρα Χ. Η τελευταία πρόταση του προγράμματος είναι πάλι 
μιά εμφάνιση ενός απλόυ μηνύματος που ειδοποιεί γιά τον τερματισμό του 
προγράμματος. 

Ανάμεσα στις δύο προτάσεις εκτύπωσης υπάρχει μιά επανάληψη do-while το 
σώμα της οποίας περιέχει δύο νέες συναρτήσεις. Η συνάρτηση getchar διαβάζει 
έναν χαρακτήρα από το πληκτρολόγιο (πιό συγκεκριμένα από την βασική 
συσκευή εισόδου STandarD INput, που έχει την ονομασία stdin στη C). Ο 
χαρακτήρας που διαβάζεται επιστρέφεται στο κυρίως πρόγραμμα μέσω μιάς 
πρότασης return όπως είναι φανερό από τη σύνταξη της πρότασης. Πράγματι 
στο αρχείο κεφαλής STDIO.H μπορούμε να βρούμε μιά δήλωση προτύπου της 
μορφής
 
int getchar(void);

Η συνάρτηση putchar γράφει έναν χαρακτήρα στην οθόνη (πιό συγκεκριμένα 
σην βασική συσκευή εξόδου STandarD OUTput, που έχει την ονομασία stdout 
στη C). Ο χαρακτήρας που γράφεται περνά στη συνάρτηση μέσω μιάς παραμέτρου 
τιμής. Στο αρχείο κεφαλής βρίσκουμε τη δήλωση προτύπου
 
int putchar(int c);

Διαπιστώνουμε οτι και στις δύο συναρτήσεις χρησιμοποιείται ο τύπος int αντί 
του char ως επικρατέστερος, αφού η μετατροπή από int σε char και αντίστροφα 
γίνεται αυτόματα και χωρίς προβλήματα. Επίσης διαπιστώνουμε οτι η συνάρτηση 
putchar επιστρέφει μιά τιμή με return και άν ανατρέξουμε στο εγχειρίδιο του 
μεταφραστή μας θα δούμε οτι η τιμή που επιστρέφεται είναι ο χαρακτήρας που 
γράφτηκε εκτός και αν το γράψιμο αποτύχει γιά κάποιο λόγο, οπότε 
επιστρέφεται η τιμή -1.

Με την ευκαιρία αυτή ας μελετήσουμε και τη δήλωση προτύπου της συνάρτησης 
printf. Έχει τη μορφή
 
int printf(char *format_string [,argument...]);

Ο πίνακας χαρακτήρων format_string δεν είναι άλλος από τη συμβολοσειρά 
ελέγχου που περιέχει και τα μηνύματα προς εκτύπωση. Προσέξτε τη δήλωση του 
πίνακα. Αντί γιά τη συνηθισμένη format_string[] έχουμε την εναλλακτική 
δήλωση δείκτη *format_string. Αυτή η μορφή είναι πολύ συνηθισμένη στη C 
ειδικά όταν το μέγεθος του πίνακα είναι ακαθόριστο. Το τμήμα των ορισμάτων 
(arguments) θα εξηγηθεί αργότερα. Η τιμή που επιστρέφει η συνάρτηση είναι ο 
αριθμός των επιτυχημένων εκτυπώσεων ορισμάτων. Η τιμή είναι 0 εάν εκτυπωθεί 
απλό μήνυμα και -1 εάν η εκτύπωση αποτύχει. Προσοχή οτι παρ' όλο οτι η τιμή 
αυτή επιστρέφεται καθε φορά που χρησιμοποιούμε τη printf εμείς δεν είναι 
απαρίτητο να την αποθηκεύσουμε κάπου.

Ας επιστρέψουμε στην εκτέλεση του προγράμματος. Το αποτέλεσμα που θα 
πάρουμε έχει τη μορφή 

Enter any characters, X = halt program.

...X
...X

End of program.

όπου τα σύμβολα ... αντιστοιχούν στους χαρακτήρες που θα εισαχθούν από τον 
χρήστη. Στη εκτέλεση του προγράμματος σας περιμένουν ορισμένες εκπλήξεις. 
Οταν εισάγετε τους χαρακτήρες τους βλέπετε αμέσως να εμφανίζονται στην 
οθόνη, όπως περιμένατε. Εάν όμως εισάγετε τον χαρακτήρα Χ το πρόγραμμα δεν 
τερματίζεται αλλά συνεχίζει την εκτύπωση των χαρακτήρων. Εάν πατήσετε το 
πλήκτρo Enter τότε διαπιστώνετε οτι επιτέλους το πρόγραμμα τερματίζεται και 
η σειρά των χαρακτήρων που μόλις πληκτρολογήσατε ξαναεμφανίζεται, μέχρι 
τον πρώτο χαρακτήρα Χ που εισάγατε. Οι υπόλοιποι αγνοούνται. Εάν πάλι 
εισάγετε νόμιμους χαρακτήρες και πατήσετε το Enter πάλι θα τους δείτε να 
εμφανίζονται όλοι μαζί σε νέα σειρά. Η εξήγηση βασίζεται στη λειτουργία του 
DOS.
Είσοδος και έξοδος στο DOS

Όταν ένα πρόγραμμα διαβάζει χαρακτήρες από το πληκτρολόγιο, σε περιβάλλον 
DOS, οι χαρακτήρες αποθηκεύονται σε μιά ειδική περιοχή μνήμης, που λέγεται 
απομονωτής πληκτρολογίου (keyboard buffer). Ταυτόχρονα, καθε πάτημα 
πλήκτρου 'αντηχείται' αυτόματα στη οθόνη (echo). Έτσι οι χαρακτήρες που 
βλέπουμε στην οθόνη μόλις πατούμε ένα πλήκτρο δεν είναι η απάντηση του 
προγράμματος (δηλαδή putchar μετά από getchar) αλλά η αντήχηση του DOS. Η 
αντήχηση μπορεί να διακοπεί φυσικά όπως θα δούμε παρακάτω (θυμηθείτε γιά 
παράδειγμα την εντολή echo off στα αρχεία δέσμης του DOS). 

Το πρόγραμμα παραλαμβάνει τους χαρακτήρες προς ανάγνωση μόνο αν 
πατήσουμε το πλήκτρο Enter. Τότε αρχίζει να εκτελείται ουσιατικά η 
επανάληψη do-while και όχι όταν εισάγουμε τους χαρακτήρες. Η συνάρτηση 
getchar επομένως διαβάζει χαρακτήρες από τον απομονωτή πληκτρολογίου και 
όχι από το πληκτρολόγιο και μόνο όταν συνοδεύονται από Enter. Το 
αποτέλεσμα της putchar επομένως είναι η νέα σειρά χαρακτήρων που 
εκτυπώνονται. 

Τα παραπάνω εξηγούν τις εκπλήξεις που συνατήσαμε στην εκτέλεση του 
προγράμματος. Όσα Χ και άν εισάγουμε αυτά δεν ενεργοποιούν την συνθήκη του 
while Απαρά μόνο αν διαβαστούν από το πρόγραμμα, δηλαδή αν πατήσουμε το 
Enter. Αλλοιώς μένουν στον απομονωτή πληκτρολογίου. Οταν τελικά διαβαστεί 
η σιρά το πρώτο Χ που συνατά το πρόγραμμα προκαλεί τον τερματισμό του. 
Επομένως οι υπόλοιποι χαρακτήρες που έμοιαζε σαν να δαιβάστηκαν κατ΄ αρχή 
από το πρόγραμμα καταλαβαίνουμε οτι δαιβαστηκαν μόνο από το DOS, ενώ το 
πρόγραμμα δούλεψε σωστά διαβάζοντας μόνο ως το πρώτο Χ, και μέχρι εκεί 
εκτυπώνει. 

Αν πάλι εισάγουμε πολλούς νόμιμους χαρακτήρες με Enter στο τέλος, τότε το 
πρόγραμμα εμφανίζει στην οθόνη όλους τους χαρακτήρες, και το Enter, και μετά 
περιμένει να εισάγουμε νέους χαρακτήρες και ένα νέο Enter γιά ν ατου 
επιτρέψει το DOS να ελέγξει τη νέα σειρά.

Περιεχόμενα Κεφαλαίου