Συμβολοσειρές. 1 Συμβολοσειρές. 6 Απριλίου 2014

Σχετικά έγγραφα
3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Μεταβλητές τύπου χαρακτήρα

2ο σετ σημειώσεων. 1 Εντολές εκτέλεσης υπό συνθήκη. 19 Μαρτίου 2012

Σημειώσεις για πρόοδο στο εργαστήριο

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

Εντολές ελέγχου ροής if, for, while, do-while

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

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

5ο σετ σημειώσεων - Δείκτες

ΑΣΚΗΣΗ 7: ΑΛΦΑΡΙΘΜΗΤΙΚΑ

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

Προγραμματισμός Ι. Χαρακτήρες. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Στη C++ υπάρχουν τρεις τύποι βρόχων: (a) while, (b) do while, και (c) for. Ακολουθεί η σύνταξη για κάθε μια:

ΑΣΚΗΣΗ 2: ΔΟΜΗ ΠΡΟΓΡΑΜΜΑΤΟΣ C, ΧΕΙΡΙΣΜΟΣ ΜΕΤΑΒΛΗΤΩΝ ΚΑΙ ΣΥΝΑΡΤΗΣΕΙΣ ΕΙΣΟΔΟΥ ΚΑΙ ΕΞΟΔΟΥ

scanf() scanf() stdin scanf() printf() int float double %lf float

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

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

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

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

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

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

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

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

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Γλώσσα Προγραμματισμού C

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

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

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

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

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

Σύντομες εισαγωγικές σημειώσεις για την. Matlab

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

5. ΒΡΟΧΟΙ ΕΠΑΝΑΛΗΨΗΣ (Β' μέρος: while - do..while)

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Κεφάλαιο Αλφαριθμητικές Σειρές Χαρακτήρων (Strings) (Διάλεξη 20) 1) Strings στη C

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

Προγραμματισμός Η/Υ Ι (Χρήση της C) 6 η Θεωρία ΜΟΝΟΔΙΑΣΤΑΤΟΙ ΠΙΝΑΚΕΣ

Ινστιτούτο Επαγγελµατική Κατάρτιση Κορυδαλλού "ΤΕΧΝΙΚΟΣ ΣΥΣΤΗΜΑΤΩΝ ΥΠΟΛΟΓΙΣΤΩΝ" (Ερωτήσεις Πιστοποίησης στην γλώσσα προγραµµατισµού C)

Εισαγωγή στον προγραμματισμό. Τμήμα Πληροφορικής & Επικοινωνιών ΤΕΙ Σερρών Εργαστήριο 2

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Εισαγωγή στους Αλγόριθμους και τον Προγραμματισμό. 3η Διάλεξη Είσοδος Δεδομένων Συνθήκες Βρόχοι Παραδείγματα

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

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

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

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

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

Κεφάλαιο ΙV: Δείκτες και πίνακες. 4.1 Δείκτες.

ΕΡΓΑΣΤΗΡΙΟ 3: Προγραμματιστικά Περιβάλλοντα και το Πρώτο Πρόγραμμα C

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

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

Οι εντολές ελέγχου της ροής ενός προγράμματος.

Προβλήματα, αλγόριθμοι, ψευδοκώδικας

Δομή Προγράμματος C++, Χειρισμός Μεταβλητών και Συναρτήσεις Εισόδου - Εξόδου

Λύσεις για τις ασκήσεις του lab5

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

2 η Διάλεξη C++ Δρ. Χρήστος Δρόσος ΑΕΙ ΠΕΙΡΑΙΑ ΤΤ ΤΜΗΜΑ ΑΥΤΟΜΑΤΙΣΜΟΥ

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

Σκοπός. Εργαστήριο 6 Εντολές Επανάληψης

γρηγορότερα. Αν θέλουμε να μηδενίσουμε όλα τα υπόλοιπα bit μπορούμε να χρησιμοποιήσουμε την εντολή:

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

ΚΕΦΑΛΑΙΟ 9 ΒΑΣΙΚΕΣ ΕΝΤΟΛΕΣ

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

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

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

char name[5]; /* define a string of characters */

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

Αναφορά (1/2) Μπορούμε να ορίσουμε μια άλλη, ισοδύναμη αλλά ίσως πιο σύντομη, ονομασία για ποσότητα (μεταβλητή, σταθερή, συνάρτηση, κλπ.

Γ7.1 Επανάληψη ύλης Β Λυκείου. Γ Λυκείου Κατεύθυνσης

Βαθμός Σχόλια. lab PASS 1194 PASS 1238 PASS 1239 PASS

Εισαγωγή στις Συναρτήσεις

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

Master Mind εφαρμογή στη γλώσσα προγραμματισμού C

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

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

1η+2η εβδομάδα. 1 Ιστορία της C. 5 Μαρτίου 2012

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

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

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

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

9. Εντολές επανάληψηςκαι η εντολή

Παραδείγματα. Γράψτε ένα πρόγραμμα που να τυπώνει τη μέση τιμή ενός συνόλου μη αρνητικών αριθμών

C: Από τη Θεωρία στην Εφαρµογή 2 ο Κεφάλαιο

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

ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ ΗΛΕΚΤΡΟΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Πως θα αποθηκεύσει τη λίστα με τα ψώνια του και θα την ανακτήσει στο Σ/Μ; και πως θα προσθέσει στη λίστα του επιπλέον προϊόντα;

Pascal, απλοί τύποι, τελεστές και εκφράσεις

Κεφάλαιο 2.6: Είσοδος / Έξοδος εδοµένων, Μορφοποίηση εδοµένων Εξόδου. ( ιάλεξη 7) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Κεφάλαιο 2.6: Είσοδος / Έξοδος Δεδομένων, Μορφοποίηση Δεδομένων Εξόδου. (Διάλεξη 7) Είσοδος/ Έξοδος

4. ΒΡΟΧΟΙ ΕΠΑΝΑΛΗΨΗΣ (Α' μέρος: for)

8. Συνθήκες ελέγχου, λογικοί τελεστές

Προγραμματισμός Η/Υ. Ενότητα 2β: Εισαγωγή στη C (Μέρος Δεύτερο)

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

Χpήσιµες Βιβλιοθήκες της γλώσσας C

Τεχνολογία και Προγραμματισμός Υπολογιστών. Η γλώσσα προγραμματισμού C

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

Transcript:

Συμβολοσειρές 6 Απριλίου 2014 1 Συμβολοσειρές Μια ειδική χρήση των πινάκων είναι αυτή της παράστασης κειμένων. Η επεξεργασία κειμένου είναι μια διαδεμόνη υπολογιστική εφαρμογή. Τα κείμενα παριστάνονται στη μνήμη του υπολογιστή ως διαδοχικοί χαρακτήρες. Είναι φυσικό λοιπόν στη C να αποθηκεύονται σε πίνακες χαρακτήρων. Στο παράδειγμα 1 βλέπουμε πώς μπορούμε να αποθηκεύσουμε τους διαδοχικούς χαρακτήρες της λέξης Hello! σε έναν πίνακα και στη συνέχεια τυπώνοντάς τους έναν προς έναν να έχουμε το οπτικό αποτέλεσμα της εκτύπωσης μιας λέξης. Listing 1: Πίνακας χαρακτήρων 2 3 int main() 4 { 5 char p[6]; 6 int i; 7 p[0] = 'H'; p[1] = 'e'; p[2] = 'l'; 8 p[3] = 'l'; p[4] = 'o'; p[5] = '!'; 9 for (i = 0; i < 6; ++i) 11 printf("%c", p[i]); 12 13 return 0; 14 } Βέβαια, στο συγκεκριμένο παράδειγμα βλέπουμε διάφορες λεπτομέρειες που θα μπορούσαν να ενοχλήσουν κάποιον όπως για παράδειγμα το ότι ο πίνακας p δηλώθηκε να έχει τόσο μέγεθος όσο και η λέξη που θέλαμε να αποθηκεύσουμε. Αυτό όμως είναι πρακτικά ανεφάρμοστο, δηλαδή δεν μπορούμε να ξέρουμε εκ των προτέρων πόσο μεγάλα θα είναι τα κείμενα που θα χρειαστεί να επεξεργαστούμε. Συνήθως λοιπόν δηλώνουμε τους πίνακες που θα χρησιμοποιήσουμε αρκετά μεγάλους για να χωράνε την πλειοψηφία των κειμένων που θα μπορούσαν να προκύψουν στην πράξη, π.χ. στο παραπάνω παράδειγμα θα δηλώναμε τον πίνακα p ως πίνακα 0 θέσεων. Αμέσως προκύπτει το επόμενο ζήτημα, ότι εφόσον δηλώνουμε τους πίνακες αρκετά μεγαλύτερους από όσο συνήθως 1

χρειάζεται, πώς μπορούμε να γνωρίζουμε πόσους ακριβώς χαρακτήρες περιέχει το κείμενο που αποθηκεύεται εκεί. Στη C το τέλος του κειμένου που αποθηκεύεται σε έναν πίνακα δηλώνεται με έναν ειδικό χαρακτήρα, το χαρακτήρα τερματισμού συμβολοσειράς ο οποίος ως χαρακτήρας είναι ο '\0' και έχει την αριθμητική τιμή 0. Έτσι, μπορούμε να γράψουμε συναρτήσεις χειρισμού κειμένου οι οποίες να δουλεύουν χωρίς να χρειάζεται να γνωρίζουν εκ των προτέρων το μήκος του κειμένου. Στη C αυτή η δομή, δηλαδή μία σειρά χαρακτήρων της οποίας το τέλος δηλώνεται με τον ειδικό χαρακτήρα '\0' ονομάζεται συμβολοσειρά (string). Πολλές συναρτήσεις των βιβλιοθηκών της C, δουλεύουν πάνω σε τέτοιου τύπου δομές. Μία από αυτές είναι η συνάρτηση printf η οποία αν της δοθεί ως παράμετρος μία συμβολοσειρά την τυπώνει στην οθόνη. Δηλαδή αναλαμβάνει να κάνει αυτό που κάναμε εμείς με το χέρι στο προηγούμενο παράδειγμα στις γραμμές και 11 τυπώνοντας τους χαρακτήρες έναν προς έναν. Χρησιμοποιούμε την printf για να τυπώνουμε συμβολοσειρές όπως στο παρακάτω παράδειγμα, δίνοντας τον πίνακα στον οποίο είναι αποθηκευμένη η συμβολοσειρά ως παράμετρο στην printf και χρησιμοποιώντας τον προσδιοριστή %s: 1 char s[0]; 2 p[0] = 'H'; p[1] = 'e'; p[2] = 'l'; 3 p[3] = 'l'; p[4] = 'o'; p[5] = '!'; 4 p[6] = '\0'; 5 printf("%s", p); Επίσης υπάρχουν διάφορες συναρτήσεις για την αντίστροφη δουλειά, δηλαδή που γεμίζουν έναν άδειο πίνακα με μία συμβολοσειρά. Π.χ. η συνάρτηση gets ¹ δέχεται παράμετρο έναν πίνακα χαρακτήρων και βάζει σε αυτόν έναν προς έναν τους χαρακτήρες που έγραψε ο χρήστης στο πληκτρολόγιο μέχρι να πατήσει το enter. Επίσης, προσθέτει το χαρακτήρα τερματισμού συμβολοσειράς. Π.χ. το παρακάτω παράδειγμα τυπώνει στην οθόνη ό,τι έγραψε ο χρήστης στο πληκτρολόγιο. 1 char p[0]; 2 gets(p); 3 printf(" Egrapses %s", p); H λειτουργία της gets είναι λίγο-πολύ η εξής: Ο πρώτος χαρακτήρας που θα γράψει ο χρήστης στο πληκτρολόγιο αποθηκεύεται στη θέση p[0] του πίνακα, ο επόμενος στη θέση p[1] κοκ. Η διαδικασία συνεχίζεται μέχρι ο χρήστης να πατήσει το enter. Ο ίδιος ο χαρακτήρας '\n' που αντιστοιχεί στο πλήκτρο enter δεν αποθηκεύεται στον πίνακα p. Αντί για αυτόν, αποθηκεύεται ο χαρακτήρας τερματισμού συμβολοσειράς '\0'. Έτσι η printf που ακολουθεί μπορεί να εντοπίσει το τέλος της συμβολοσειράς και να τυπώσει μόνο όσους από τους 0 χαρακτήρες του πίνακα p χρειάζονται. Μια υλοποίηση της gets θα μπορούσε να είναι και η παρακάτω: Listing 2: Πιθανή υλοποίηση της gets 2 ¹Η gets είναι μία συνάρτηση που δεν πρέπει να χρησιμοποιείται γιατί έχει κάποια σοβαρή σχεδιαστική ατέλεια. Θα δούμε στη συνέχεια ποιες συναρτήσεις θα έπρεπε κανείς να χρησιμοποιεί για αυτή τη δουλειά. Λόγω της απλότητάς της όμως θα την χρησιομοποιήσουμε προς το παρόν για τα παραδείγματά μας, τονίζοντας βέβαια ότι δεν πρέπει να χρησιμποιείται σε πραγματικές συνθήκες. 2

3 int main() 4 { 5 char p[0]; 6 char c; 7 int i; 8 9 i = 0; do { 11 c = getchar(); 12 if (c == '\n') 13 p[i] = '\0'; 14 else { 15 p[i] = c; 16 i++; 17 } 18 } while (c!= '\n'); 19 20 return 0; 21 } Ο βρόχος do-while των γραμμών -18 επαναλαμβάνεται όσο ο χαρακτήρας που έδωσε ο χρήστης στη γραμμή 11 δεν είναι το enter. Όσο ο χαρακτήρας δεν είναι το enter, αποθηκεύεται στην i- οστή θέση του πίνακα p. Σε κάθε επανάληψη του βρόχου η μεταβλητή i αυξάνεται κατά ένα ώστε ο επόμενος χαρακτήρας να αποθηκευτεί στην επόμενη ελεύθερη θέση (γραμμές 14-17). Στην περίπτωση που ο χαρακτήρας είναι το enter, ισχύει η συνθήκη της γραμμής 12 οπότε στην θέση που θα εποθηκευόταν ο επόμενος χαρακτήρας, αποθηκεύται ο χαρακτήρας τερματισμού συμβολοσειράς (γραμμές 12-13). Αντίστοιχα, μια υλοποίηση της εκτύπωσης συμβολοσειρών με τον προσδιοριστή %s της printf θα μπορούσε να είναι η εξής: Listing 3: Πιθανή υλοποίηση της printf 2 3 int main() 4 { 5 char p[0]; 6 int i; 7 8 printf(" Dose mia symvoloseira: "); 9 gets(p); 11 i = 0; 12 while (p[i]!= '\0') /* while (p[i]) */ 13 printf("%c", p[i++]); 14 15 return 0; 3

16 } Σε αυτό το παράδειγμα, ζητείται από το χρήστη μία συμβολοσειρά στις γραμμές 8-9 η οποία αποθηκεύεται στον πίνακα p. Στη συνέχεια ο πίνακας p σαρώνεται από τη θέση i=0 και για αυξανόμενες τιμές του i με το βρόχο των γραμμών 12-13. Ο βρόχος επαναλαμβάνεται όσο ο χαρακτήρας p[i] δεν είναι ίσος με τον χαρακτήρα τερματισμού συμβολοσειράς '\0'. Παρατηρήστε ότι τη συνθήκη while (p[i]!= '\0') θα μπορούσαμε να τη γράψουμε απλούστερα ως while (p[i]) αφού ο χαρακτήρας '\0' έχει την τιμή μηδέν. Σε κάθε επανάληψη του βρόχου, τυπώνεται ο χαρακτήρας p[i] και η τιμή της μεταβλητής i αυξάνεται κατά ένα με τον μεταθεματικό τελεστή μοναδιαίας αυτοαύξησης. Η επεξεργασία συμβολοσειρών και κειμένων λοιπόν ανάγεται σε επεξεργασία πινάκων χαρακτήρων. Η βιβλιοθήκη της C παρέχει διάφορες συναρτήσεις χειρισμού συμβολοσειρών μερικές από τις οποίες παραθέτουμε στο τέλος. Μία συνηθισμένη λειτουργία πάνω σε γραμματοσειρές είναι η καταμέτρηση των χαρακτήρων τους, δηλαδή του μήκους τους. Το παρακάτω παράδειγμα ζητάει μία συμβολοσειρά από το χρήστη και εκτυπώνει το μήκος της: 2 3 int main() 4 { 5 char p[0]; 6 int i; 7 8 printf(" Dose symvoloseira: "); 9 gets(p); 11 for (i = 0; p[i]; i++) 12 ; 13 Listing 4: Μέτρηση μήκους συμβολοσειράς 14 printf(" To mikos tis symvoloseiras einai: %d\n", i); 15 return 0; 16 } Την μέτρηση την κάνει ο βρόχος for της γραμμής 11. Εκεί αρχικοποιείται η μεταβλητή i που θα διατρέξει τον πίνακα p. Όσο το στοιχείο p[i] δεν είναι μηδέν, δηλαδή το p[i] δεν είναι ο χαρακτήρας τερματισμού συμβολοσειράς, το i αυξάνεται κατά ένα. Όταν τελικά ο βρόχος σταματήσει, το i θα είναι ο αριθμός των χαρακτήρων που διαβάστηκαν. Παρατηρήστε ότι ο βρόχος δεν έχει σώμα: Απλώς υπάρχει ένα ερωτηματικό που στην ουσία είναι η κενή εντολή. Η βιβλιοθήκη της C παρέχει αυτήν τη λειτουργικότητα με τη συνάρτηση strlen(p) της βιβλιοθήκης string. Μπορείτε να τη χρησιμοποιήσετε ανάφεροντας στο πρόγραμμά σας #include <string.h>. Στο παρακάτω παράδειγμα ζητούνται από το χρήστη μία συμβολοσειρά και ένας χαρακτήρας. Αν ο χαρακτήρας υπάρχει στη συμβολοσειρά το πρόγραμμα τυπώνει τη θέση στην οποία βρίσκεται, αλλιώς τυπώνει σχετικό μήνυμα. Ο βρόχος των γραμμών 15-17 διατρέχει τη συμβολοσειρά. Σε κάθε επανάληψη, ελέγχεται να ο τρέχον χαρακτήρας είναι ίδιος με εκείνον που έδωσε ο χρήστης. Αν συμβαίνει κάτι τέτοιο τότε ο βρόχος τερματίζεται με την break. Τελικά, η ροή εκτέλεσης 4

του προγράμματος θα φτάσει στη γραμμή 19 είτε αν ο χαρακτήρας βρεθεί, είτε αν ο βρόχος διατρέξει όλους τους χαρακτήρες της συμβολοσειράς χωρίς να βρει τον ζητούμενο. Σε αυτήν την περίπτωση ο δείκτης i θα δείχνει τον χαρακτήρα τερματισμού της συμβολοσειράς. Αυτήν ακριβώς τη συνθήκη εξετάζει η if της γραμμής 19: Αν το i δείχνει σε κάποιο μη-μηδενικό χαρακτήρα, τότε αυτός βρίσκεται μέσα στη συμβολοσειρά και αυτό θα συμβεί αν έχει εκτελεστεί η break. Στην αντίθετη περίπτωση, το i δείχνει τον χαρακτήρα τερματισμού της συμβολοσειράς που σημαίνει ότι εκτελέστηκαν όλες οι επαναλήψεις του βρόχου χωρίς δηλαδή να βρεθεί ο χαρακτήρας. 2 # include <string.h> Listing 5: Αναζήτηση χαρακτήρα 3 4 int main() 5 { 6 char p[0]; 7 char c; 8 int i; 9 printf(" Dose symvoloseira: "); 11 gets(p); 12 printf(" Dose xaraktira: "); 13 c = getchar(); 14 15 for (i = 0; i < strlen(p); i++) 16 if (p[i] == c) 17 break; 18 19 if (p[i]) 20 printf("o xaraktnras brethike sth thesi %d\n", i); 21 else 22 printf("o xaraktnras den brethike stn symboloseira\n"); 23 24 return 0; 25 } Το επόμενο παράδειγμα ζητάει δύο συμβολοσειρές από το χρήστη και τις συνενώνει γράφοντας τη δεύτερη μετά το τέλος της πρώτης. Στη γραμμή 15 κρατάμε στη μεταβλητή j το μήκος της πρώτης συμβολοσειράς. Στη θέση p1[j] θα βρίσκεται ο χαρακτήρας τερματισμού της πρώτης συμβολοσειράς. Από αυτόν τον χαρακτήρα και μετά γράφονται ένας προς ένα οι χαρακτήρες της δεύτερης συμβολοσειράς. Ο βρόχος της γραμμής 16 εκτελεί μία επανάληψη παραπάνω από τους χαρακτήρες της συμβολοσειράς (παρατηρήστε το i <= strlen(p2) αντί για το συνηθισμένο i < strlen(p2)). Γιατί; 2 # include <string.h> Listing 6: Συνένωση συμβολοσειρών 5

3 4 int main() 5 { 6 char p1[0]; 7 char p2[0]; 8 int i, j; 9 printf(" Dose tnv prwtn symvoloseira: "); 11 gets( p1); 12 printf(" Dose tnv deutern symvoloseira: "); 13 gets( p2); 14 15 j = strlen(p1); 16 for (i = 0; i <= strlen( p2); i++) 17 p1[j + i] = p2[i]; 18 19 printf(" Kai oi duo mazi: %s\n", p1); 20 21 return 0; 22 } 1 Το επόμενο παράδειγμα ζητάει δύο συμβολοσειρές από το χρήστη και τις συγκρίνει αλφαβητικά. Τυπώνει ανάλογο μήνυμα. Ο βρόχος των γραμμών 18-19 σαρώνει τις συμβολοσειρές αυξάνοντας τη μεταβλητή i όσο ισχύουν τρεις συνθήκες: οι χαρακτήρες p1[i] και p2[i] είναι ίδιοι, δεν έχει βρεθεί ο χαρακτήρας τερματισμού συμβολοσειράς στην p1 και δεν έχει βρεθεί ο χαρακτήρας τερματισμού συμβολοσειράς στην p2. Αν κάποια από αυτές τις συνθήκες δεν ισχύει, τότε ο βρόχος σταματάει και η μεταβλητή i δείχνει τη θέση στην οποία αυτό συνέβη. Φτάνοντας λοιπόν στη γραμμή 20 ξέρουμε ότι συγκρίνοντας τις συμβολοσειρές στη θέση i μπορούμε να βρούμε ποια είναι μικρότερη. Αν ο i-οστός χαρακτήρας της p1 είναι μικρότερος από τον αντίστοιχο της p2². 2 # include <stdio.h> 3 # include <string.h> 4 5 int main() 6 { 7 char p1[0]; 8 char p2[0]; 9 int i, j; Listing 7: Σύγκριση συμβολοσειρών 11 printf(" Dose tnv prwtn symvoloseira: "); 12 gets( p1); ²Μικρότερος χαρακτήρας σημαίνει μικρότερος ASCII κωδικός και το αντίστροφο. Η λογική με την οποία υλοποιούμε τη σύγκριση καλύπτει και την περίπτωση που βρεθεί ο χαρακτήρας τερματισμού συμβολοσειράς ο οποίος έχει τιμή μηδέν και είναι προφανώς μικρότερος από οποιονδήποτε άλλο 6

13 printf(" Dose tnv deutern symvoloseira: "); 14 gets( p2); 15 16 i = 0; 17 while (p1[i] == p2[i] && p1[i] && p2[i]) 18 i++; 19 20 if ( p1[i] < p2[i]) 21 printf("h prwtn einai mikrotern alfabhtika\n"); 22 else if ( p2[i] < p1[i]) 23 printf("h deutern einai mikrotern alfabhtika\n"); 24 else 25 printf(" Oi dyo symboloseires einai ises\n"); 26 27 return 0; 28 } Το επόμενο παράδειγμα δείχνει περίπου τι κάνει η C όταν χρησιμοποιούμε τον specifier %d στη scanf για να εισάγει ο χρήστης ένα δεκαδικό αριθμό από το πληκτρολόγιο. Παρόλο που η λειτουργία που υλοποιεί η scanf είναι προφανής, η διαδικασία υλοποίησής της δεν είναι άμεση. Ο λόγος είναι ότι όταν ο χρήστης πληκτρολογεί ένα αριθμό στο δεκαδικό σύστημα αρίθμησης, σε όρους της μηχανής απλώς στέλνει διαδοχικούς κωδικούς με το πληκτρολόγιο στο πρόγραμμα. Αυτοί οι κωδικοί αντιστοιχίζονται με τον πίνακα ASCII σε αριθμητικά ψηφία. Οι κωδικοί και οι αντίστοιχες αριθμητικές αξίες των ψηφίων που αναπαριστούν δεν ταυτίζονται. Ο χαρακτήρας 0 για παράδειγμα έχει κωδικό ASCII 48. Παραπέρα, δεν έχουν όλα τα αριθμητικά ψηφία την ίδια σημασία. Η σημασία τους εξαρτάται από τη θέση στην οποία βρίσκονται και από τη βάση του συστήματος αρίθμησης που χρησιμοποιείται. Στο δεκαδικό σύστημα ένα ψηφίο στην δεξιότερη θέση ενός αριθμού έχει τόση αξία όσο και ο αριθμός που αναπαριστά. Στην επόμενη προς τα αριστερά θέση το ψηφίο έχει τη δεκαπλάσια αξία, στην επόμενη εκατονταπλάσια κοκ. Τελικά, το πρόγραμμα αποθηκεύει τους αριθμούς που έδωσε ο χρήστης ως συμβολοσειρά σε έναν πίνακα χαρακτήρων. Στη συνέχεια διατρέχει τους χαρακτήρες που έδωσε ο χρήστης από τα δεξιά προς τα αριστερά (δείτε τη for στη γραμμή 14). Κάθε ένα χαρακτήρα τον μετατρέπει στην αριθμητική αξία του ψηφίου που αναπαριστά αφαιρώντας του τον ASCII κωδικό του μηδέν (p[i] - '0'). Την αριθμητική αυτή αξία την πολλαπλασιάζει με τη μεταβλητή multiplier η οποία εκφράζει την αξία της θέσης που βρίσκεται το ψηφίο. Στην πρώτη επανάληψη η multiplier είναι 1, στην επόμενη, στην επόμενη 0 κοκ. Αυτό που προκύπτει είναι η αριθμητική αξία του χαρακτήρα που εξετάζεται στην τρέχουσα επανάληψη και είναι η παράσταση δεξία από το += της γραμμής 15. Αυτή η αξία προστίθεται στη μεταβλητή number η οποία είναι ο συνολικός αθροιστής που τελικά κρατάει την αξία του αριθμού. 2 # include <string.h> 3 4 int main() 5 { Listing 8: Μετατροπή συμβολοσειράς σε ακέραιο 7

6 char p[0]; 7 int multiplier = 1; 8 int number = 0; 9 int i; 11 printf(" Dose ena dekadiko arithmo: "); 12 gets(p); 13 14 for (i = strlen(p) - 1; i >= 0; --i) { 15 number += (p[i] - '0') * multiplier; 16 multiplier *= ; 17 } 18 19 printf(" Edoses ton arithmo %d\n", number); 20 21 return 0; 22 } Το επόμενο παράδειγμα ζητάει από το χρήστη να εισάγει διαρκώς κείμενο. Η διαδικασία τερματίζει όταν ο χρήστης εισάγει μία κενή γραμμή. Το πρόγραμμα μετράει το πλήθος των εμφανίσεων του κάθε χαρακτήρα αγνοώντας αν είναι πεζός ή κεφαλαίος. 2 # include <string.h> 3 # include <ctype.h> Listing 9: Συχνότητα εμφανίσεων 4 5 int main() 6 { 7 char p[0]; 8 int freq[26]; 9 int i; 11 for (i = 0; i < 26; ++i) 12 freq[i] = 0; 13 14 printf(" Dwste keimevo. Mia kevn grammn termatizei tn diadikasia.\ n"); 15 do { 16 gets(p); 17 for (i = 0; i < strlen(p); ++i) 18 if (isalpha(p[i])) { 19 if (islower(p[i])) 20 freq[p[i] - 'a']++; 21 else 22 freq[p[i] - 'A']++; 23 } 8

24 } while (strlen(p)); 25 26 printf(" Syxnotites:\ n"); 27 for (i = 0; i < 26; ++i) 28 printf("%c: %d\n", 'a' + i, freq[i]); 29 30 return 0; 31 } 2 Συναρτήσεις βιβλιοθήκης Πολλά από τα προηγούμενα παραδείγματα υλοποιούνται (με καλύτερο τρόπο) στις στάνταρ βιβλιοθήκες της C. Στον πίνακα που ακολουθεί παραθέτουμε ορισμένες από τις συναρτήσεις βιβλιοθήκης. Για μια πληρέστερη ενημέρωση ανατρέξτε στις συναρτήσεις της βιβλιοθήκης strings και string. Πίνακας 1: Συναρτήσεις χειρισμού συμβολοσειρών strlen(p) strcasecmp(p1, p2) strchr(p, c) strcat(p1, p2) strstr(haystack, needle) Επιστρέφει το μήκος της συμβολοσειράς p Συγκρίνει δύο συμβολοσειρές p1 και p2 Βρίσκει το χαρακτήρα c στην p αν υπάρχει Συνενώνει τις p1 και p2 γράφοντας την p2 μετά την p1 Ψάχνει αν η συμβολοσειρά needle περιέχεται στην haystack 3 Παράρτημα - Code::Blocks Help plugin Το περιβάλλον ανάπτυξης Code::Blocks παρέχει ένα plugin εμφάνισης των σελίδων τεκμηρίωσης των συναρτήσεων της C. Σε περιβάλλον Windows αυτό δεν μπορεί να εγκατασταθεί με το χέρι αλλά μόνο μέσα από την επιλογή Contrib plugins κατά τη διάρκεια της αρχικής εγκατάστασης. Για να εγκαταστήσετε τις σελίδες τεκμηρίωσης κατεβάστε τις από το https://www.kernel.org/doc/manpages/download.html ή από το http://www.syros.aegean.gr/users/quasi/iek/tep/c/downloads/man3.zip. Αυτές είναι όλες οι σελίδες τεκμηρίωσης του Linux τις οποίες δεν χρειάζεστε όλες. Εκείνες που αφορούν τη C βρίσκονται στον κατάλογο man3. Αποθηκεύστε τις σε όποιο σημείο προτιμάτε και στη συνέχεια μέσα από το Code::Blocks επιλέξτε Settings, Environment, Help files. Στη συνέχεια επιλέξτε Add και στο διαλογικό παράθυρο που εμφανίζεται διαλέξτε ένα οποιοδήποτε όνομα της αρεσκείας σας, π.χ. man pages. Στο επόμενο παράθυρο που σας προτρέπει να ψάξετε για το αρχείο πατήστε Yes και περιηγηθείτε στον κατάλογο που θέλετε. Εδώ πρέπει να ξεγελάσετε το σύστημα που θα ψάχνει για windows help files. Στο σημείο που έχει προεπιλεγμένο τύπο το Windows help files.chm,.hlp επιλέξτε All files και επιλέξτε ένα οποιοδήποτε αρχείο και μετά OK. Στο σημείο του παραθύρου που αναφέρει το αρχείο που επιλέξατε κάντε δύο αλλαγές: Προσθέστε στην αρχή το πρόθεμα man: και σβήστε από το τέλος το όνομα του αρχείου που επιλέξατε έτσι ώστε να μείνει το 9

σημείο μέχρι το φάκελο στον οποίο βρίσκεται το αρχείο. Τώρα επιλέγοντας man pages από το μενού Help θα εμφανίζεται ένα παράθυρο στο οποίο μπορείτε να γράψετε το όνομα μίας συνάρτησης της C για να δείτε την τεκμηρίωσή της.