1 Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) ηµήτριος Κατσαρός, Ph.D. Χειµώνας 2005 ιάλεξη 7η
2 Ιστοσελίδα του µαθήµατος http://skyblue.csd.auth.gr/~dimitris/courses/cpp_fall05.htm Θα τοποθετούνται οι διαφάνειες του επόµενου µαθήµατος Επικοινωνία: dimitris@skyblue.csd.auth.gr
3 Περιεχόµενα Αλφαριθµητικά Κλάση string
4 Στόχοι εκµάθησης Χρήση της έννοιας του πίνακα για αλφαριθµητικά C-strings Εργαλεία χειρισµού χαρακτήρων Character I/O get, put συναρτήσεις putback, peek, ignore Κλάση string Επεξεργασία string
5 Εισαγωγή υο τύποι αλφαριθµητικών: C-strings Πίνακας µε βασικό τύπο char Το τέλος του αλφαριθµητικού σηµατοδοτείται µε το null, "\0" Παλιότερη µέθοδος που κληρονοµήθηκε από τη C Κλάση string Χρησιµοποιεί templates
6 C-strings Πίνακας µε βασικό τύπο char Ένας χαρακτήρας ανά indexed µεταβλητή Ένας επιπλέον χαρακτήρας: "\0" Αποκαλείται null χαρακτήρας Χαρακτήρας τέλους
7 Μεταβλητή τύπου C-string Πίνακας χαρακτήρων: char s[10]; ήλωση µεταβλητής c-string που µπορεί να κρατήσει µέχρι 9 χαρακτήρες + τον null χαρακτήρα Συνήθως µερικώς-πλήρης πίνακας ήλωση αρκετά µεγάλου µεγέθους, ώστε να µπορεί να κρατήσει το αλφαριθµητικό του µεγαλύτερου µεγέθους που µπορεί να συναντηθεί Indicate end with null Η µοναδική διαφορά από τους τυπικούς πίνακες: Πρέπει να περιέχει τον null χαρακτήρα
8 Αποθήκευση ενός C-string Τυπικός πίνακας: char s[10]; Εάν το s περιέχει το αλφαριθµητικό "Hi Mom!", θα αποθηκευτεί ως:
9 Αρχικοποίηση ενός C-string Μπορούµε να αρχικοποιήσουµε ένα c-string: char mymessage[20] = "Hi there."; εν χρειάζεται να γεµίσουµε ολόκληρο τον πίνακα Η αρχικοποίηση τοποθετεί το "\0" στο τέλος Μπορούµε να παραλείψουµε το µέγεθος του πίνακα: char shortstring[] = "abc"; Αυτόµατα κάνει το µέγεθος του πίνακα κατά ένα µεγαλύτερο από το µήκος του αλφαριθµητικού ΕΝ είναι το ίδιο µε το: char shortstring[] = {"a", "b", "c"};
10 C-string Indexes Ένα c-string ΕΙΝΑΙ ένας πίνακας Μπορούµε να προσπελάσουµε τις indexed µεταβλητές του: char ourstring[5] = "Hi"; Το ourstring[0] είναι το "H" Το ourstring[1] είναι το "i" Το ourstring[2] είναι το "\0" Το ourstring[3] είναι απροσδιόριστο Το ourstring[4] είναι απροσδιόριστο
Χειρισµός των indexes ενός C-string 11 Μπορούµε να χειριστούµε τις indexed µεταβλητές char happystring[7] = "DoBeDo"; happystring[6] = "Z"; Προσοχή! Εδώ, το "\0" (null) αντικαταστάθηκε από το "Z"! Εάν το null διαγραφεί, όπως εδώ, το c-string δεν συµπεριφέρεται πλέον όπως ένα c-string! Απροσδιόριστα αποτελέσµατα!
12 Βιβλιοθήκη ήλωση c-strings εν απαιτεί κάποια C++ βιβλιοθήκη Κοµµάτι της βασικής C++ Χειρισµός Απαιτούν τη βιβλιοθήκη <cstring> Τυπικά, τις συµπεριλαµβάνουµε όταν χρησιµοποιούµε τα c-strings
13 Τελεστές = και == µε τα C-strings Τα C-strings δεν είναι όπως οι άλλες µεταβλητές εν επιτρέπεται η ανάθεση και η σύγκριση: char astring[10]; astring = "Hello"; //ΠΑΡΑΝΟΜΟ! Μπορούµε να χρησιµοποιήσουµε την ανάθεση "=" ΜΟΝΟ στη δήλωση ενός c-string! Πρέπει να χρησιµοποιήσουµε συνάρτηση βιβλιοθήκης για ανάθεση: strcpy(astring, "Hello"); Ενσωµατωµένη συνάρτηση (στη βιβλιοθήκη <cstring>) Θέτει την τιµή του astring ίση µε "Hello" ΕΝ ελέγχει για µέγεθος! Αφήνεται στον προγραµµατιστή, όπως συµβαίνει και στους πίνακες!
14 Σύγκριση δυο C-strings Επίσης, δεν µπορούµε να χρησιµοποιήσουµε τον τελεστή == char astring[10] = "Hello"; char anotherstring[10] = "Goodbye"; astring == anotherstring; // ΕΝ επιτρέπεται! Πρέπει να χρησιµοποιήσουµε συνάρτηση βιβλιοθήκης: if (strcmp(astring, anotherstring)) cout << "Strings NOT same."; else cout << "Strings are same.";
15 Η βιβλιοθήκη <cstring> (1/2)
16 Η βιβλιοθήκη <cstring> (2/2)
17 Συναρτήσεις για C-string: strlen() Μήκος αλφαριθµητικού Συχνά είναι χρήσιµο να γνωρίζουµε το µήκος του αλφαριθµητικού: char mystring[10] = "dobedo"; cout << strlen(mystring); Επιστρέφει τον αριθµό των χαρακτήρων Το null δεν συµπεριλαµβάνεται Το αποτέλεσµα είναι: 6
18 Συναρτήσεις για C-string: strcat() Συνένωση αλφαριθµητικών Συχνά επιθυµούµε να ενώσουµε δυο αλφαριθµητικά: char stringvar[20] = "The rain"; strcat(stringvar, "in Spain"); είτε το αποτέλεσµα: Η µεταβλητή stringvar περιέχει τώρα "The rainin Spain" Προσοχή! Προσθέστε κενά όπου χρειάζεται!
19 C-strings ως ορίσµατα, παράµετροι Θυµηθείτε: ένα c-string είναι ένας πίνακας Μια παράµετρος c-string είναι µια παράµετρος πίνακα Τα c-strings που περνιούνται σε συναρτήσεις µπορεί να αλλαχτούν από την καλούµενη συνάρτηση! Όπως όλοι οι πίνακες, είναι σύνηθες να στέλνουµε και το µέγεθος ως όρισµα Η συνάρτηση θα µπορούσε βέβαια να βρει το χαρακτήρα "\0" και έτσι να προσδιορίσει το µέγεθος του αλφαριθµητικού Έτσι, το µέγεθος δεν είναι απόλυτα απαραίτητο εάν η συνάρτηση δεν θα αλλάξει την παράµετρο c-string Χρησιµοποιήστε τον "const" modifier για να προστατέψετε τα ορίσµατα c-string
20 Έξοδος για C-string Η έξοδος επιτυγχάνεται µε τον τελεστή << Το έχουµε ήδη δει: cout << news << " Wow.\n"; Όπου το news είναι µια µεταβλητή c-string Είναι δυνατό, επειδή ο τελεστής << υπερφορτώνεται για τα c-strings!
21 Είσοδος για C-string Η είσοδος επιτυγχάνεται µε τον τελεστή >> Υπάρχουν βέβαια κάποια ζητήµατα Οι λευκοί χαρακτήρες θεωρούνται "delimiter" Tab, space, line breaks παραβλέπονται Η ανάγνωση εισόδου σταµατά σε έναν delimiter Παρακολουθήστε το µέγεθος του c-string Πρέπει να είναι αρκετά µεγάλο για να κρατήσει ολόκληρο το αλφαριθµητικό! Η C++ δεν παρέχει προειδοποιήσεις σε τέτοια ζητήµατα!
22 Παράδειγµα εισόδου για C-string char a[80], b[80]; cout << "Enter input: "; cin >> a >> b; cout << a << b << "END OF OUTPUT\n"; Ο διάλογος που λαµβάνει χώρα είναι: Enter input: Do be do to you! DobeEND OF OUTPUT Σηµείωση: Το υπογραµµισµένο τµήµα πληκτρολογείται στο πληκτρολόγιο Το c-string a λαµβάνει το: "do" Το c-string b λαµβάνει το: "be"
23 Είσοδος γραµµής σε C-string Μπορούµε να λάβουµε ολόκληρη γραµµή ως τιµή σε ένα c-string Χρησιµοποιήστε τη getline(), µια προκαθορισµένη συνάρτηση: char a[80]; cout << "Enter input: "; cin.getline(a, 80); cout << a << "END OF OUTPUT\n"; Ο διάλογος που λαµβάνει χώρα είναι: Enter input: Do be do to you! Do be do to you!end OF INPUT
24 Λίγα περισσότερα για τη getline() Μπορούµε ρητά να καθορίσουµε τον αριθµό χαρακτήρων που θα λάβει: char shortstring[5]; cout << "Enter input: "; cin.getline(shortstring, 5); cout << shortstring << "END OF OUTPUT\n"; Αποτέλεσµα: Enter input: dobedowap dobeend OF OUTPUT Εξαναγκάζει να διαβαστούν ΤΕΣΣΕΡΕΙΣ µόνο χαρακτήρες Επειδή χρειάζεται χώρο για τον χαρακτήρα null!
25 I/O χαρακτήρων Είσοδος και Έξοδος δεδοµένων ΌΛΑ αντιµετωπίζονται ως χαρακτήρες π.χ., ο αριθµός 10 τυπώνεται ως "1" και "0" Η µεταροπή γίνεται αυτόµατα Χρησιµοποιεί χαµηλού επιπέδου λειτουργίες Φυσικά, µπορούµε και εµείς να χρησιµοποιήσουµε τις ίδιες χαµηλού επιπέδου λειτουργίες
26 Συνάρτηση get() ιαβάζει ένα χαρακτήρα κάθε φορά Συνάρτηση µέλος του αντικειµένου cin: char nextsymbol; cin.get(nextsymbol); ιαβάζει τον επόµενο χαρακτήρα και τον τοποθετεί στη µεταβλητή nextsymbol Το όρισµα πρέπει να είναι τύπου char Όχι "string"!
27 Συνάρτηση put() Τυπώνει ένα χαρακτήρα κάθε φορά Συνάρτηση µέλος του αντικειµένου cout: Παραδείγµατα: cout.put( a ); Τυπώνει το γράµµα "a" στην οθόνη char mystring[10] = "Hello"; cout.put( mystring[1] ); Τυπώνει το γράµµα "e" στην οθόνη
28 Κι άλλες συναρτήσεις putback() Αφού διαβαστεί κάποιος χαρακτήρας, ίσως χρειαστεί να τοποθετηθεί πίσω στο κανάλι εισόδου cin.putback( lastchar ); peek() Επιστρέφει τον επόµενο χαρακτήρα, αλλά τον αφήνει εκεί peekchar = cin.peek(); ignore() Αγνοεί την είσοδο, µέχρι τον συγκεκριµένο χαρακτήρα cin.ignore(1000, "\n"); Αγνοεί το πολύ 1000 χαρακτήρες µέχρι τον "\n"
29 Η βιβλιοθήκη <ctype> (1/3)
30 Η βιβλιοθήκη <ctype> (2/3)
31 Η βιβλιοθήκη <ctype> (3/3)
32 Η κλάση string Ορίζεται στη βιβλιοθήκη: #include <string> using namespace std; Μεταβλητές string και εκφράσεις Αντιµετωπίζονται όπως και οι απλοί τύποι Επιτρέπεται ανάθεση, σύγκριση, πρόσθεση: string s1, s2, s3; s3 = s1 + s2; //Concatenation s3 = "Hello Mom!" //Assignment Σηµειώστε ότι το c-string "Hello Mom!" µετατρέπεται αυτόµατα σε τύπο string!
33 Παράδειγµα χρήσης της string
34 I/O µε την κλάση string Όπως και για τους άλλους τύπους! string s1, s2; cin >> s1; cin >> s2; Αποτελέσµατα: Ο χρήστης πληκτρολογεί το ακόλουθο: May the hair on your toes grow long and curly! Η εξαγωγή αγνοεί τους λευκούς χαρακτήρες: Το s1 λαµβάνει την τιµή "May" Το s2 λαµβάνει την τιµή "the"
35 Η getline() µε την κλάση string Για πλήρεις γραµµές: string line; cout << "Enter a line of input: "; getline(cin, line); cout << line << "END OF OUTPUT"; Ο διάλογος που λαµβάνει χώρα: Enter a line of input: Do be do to you! Do be do to you!end OF INPUT Όµοια µε τη χρήση της getline() για c- strings
36 Άλλες εκδόσεις της getline() Μπορούµε να καθορίσουµε "delimiter" χαρακτήρα: string line; cout << "Enter input: "; getline(cin, line, "?"); Λαµβάνει είσοδο µέχρι να συναντήσει το χαρακτήρα "?" Η getline() στην ουσία επιστρέφει αναφορά string s1, s2; getline(cin, s1) >> s2; Results in: (cin) >> s2;
37 Παγίδα: Μίξη µεθόδων εισόδου Προσοχή στη µίξη cin >> var και getline int n; string line; cin >> n; getline(cin, line); Εάν η είσοδος είναι: 42 Hello hitchhiker Η µεταβλητή n τίθεται στην τιµή 42 Η µεταβλητή line τέθηκε στο κενό αλφαριθµητικό! Η cin >> n αγνοεί τους λευκούς χαρακτήρες, αφήνοντας όµως το "\n" στο ρεύµα εισόδου για την getline()!
38 Επεξεργασία για την κλάση string ιαθέσιµες οι ίδιες λειτουργίες όπως και στα c-strings Και ακόµα Πάνω από 100 µέλη της standard κλάσης string Μερικές συναρτήσεις-µέλη:.length() Επιστρέφει το µήκος της µεταβλητής string.at(i) Επιστρέφει αναφορά στο χαρακτήρα στη θέση i
39 Συναρτήσεις-µέλη της string (1/2)
40 Συναρτήσεις-µέλη της string (2/2)
Μετατροπές µεταξύ C-string και 41 αντικειµένων της κλάσης string Αυτόµατες µετατροπές τύπων Από ένα C-string σε αντικείµενο string: char acstring[] = "My C-string"; string stringvar; stringvar = acstring; Επιτρεπτό και κατάλληλο! acstring = stringvar; Μη επιτρπτό! εν µπορεί να αυτο-µετατραπεί σε C-string Χρειάζεται ρητή µετατροπή: strcpy(acstring, stringvar.c_str());
42 Περίληψη Μια µεταβλητή τύπου C-string είναι πίνακας χαρακτήρων Με την προσθήκη του ΚΕΝΟΥ χαρκτήρα (null character), "\0" Τα C-strings λειτουργούν όπως οι πίνακες εν επιτρέπουν ανάθεση και σύγκριση όπως οι απλές µεταβλητές Βιβλιοθήκες όπως οι <cctype> και <string> περιέχουν χρήσιµες συναρτήσεις διαχείρισης Η cin.get() διαβάζει τον επόµενο (µόνο) χαρακτήρα Οι εκδόσεις της getline() επιτρέπουν ανάγνωση ολόκληρων γραµµών Τα αντικείµενα της κλάσης String συµπεριφέρονται καλύτερα από ότι τα c-strings