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