Χαρακτήρες και συμβολοσειρές

Slides:



Advertisements
Παρόμοιες παρουσιάσεις
Το αλφαριθμητικό (string)
Advertisements

Ένα απλό πρόγραμμα σε C /* ********************************************* * This program prints out the sentence “This is a test.” * *********************************************
Προγραμματισμός Ι Πίνακες •Ο πίνακας είναι μία συλλογή μεταβλητών ίδιου τύπου, οι οποίες είναι αποθηκευμένες σε διαδοχικές θέσεις μνήμης. Χρησιμοποιείται.
Εφαρμογες με αριθμους και συμβολοσειρες
Προγραμματισμός Ι Παράδειγμα: Παράδειγμα:Να γραφεί πρόγραμμα που να δέχεται ως είσοδο κείμενο, να απαριθμεί τις εμφανίσεις των ψηφίων 0-9, τα λευκά διαστήματα.
Αναδρομη και static Γραψετε την συναρτηση sequence_size που διαβαζει μια απροσδιοριστου μεγεθους σειρας και υπολογιζει και τυπωνει το μεγεθος της. int.
ΜΑΘ 3122 (106) Γλώσσα προγραμματισμού
Μάθημα : Βασικά Στοιχεία της Γλώσσας Java
ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΙΑΔΙΚΑΣΤΙΚΟ ΠΡΟΓΡΑΜMΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ – ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ.
Τύποι πραγματικών αριθμών
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Πίνακες Κλάσεις και Αντικείμενα.
Συναρτήσεις Κληση/Επιστροφη Παραμετροι
ΘΠ06 - Μεταγλωττιστές Πίνακας Συμβόλων, Σημασιολογικές Ενέργειες.
ΗΥ-150 Προγραμματισμός Εντολές Ελέγχου Ροής.
Τελεστές ανάθεσης (assignment)
Κεφάλαιο 2ο Πεπερασμένα αυτόματα.
ΜΕΤΑΒΛΗΤΕΣ - ΤΥΠΟΙ ΜΑΘΗΜΑ 3.
ΕΠΑΝΑΛΗΨΗΕΠΑΝΑΛΗΨΗ ΠΡΟΓΡΑΜΜΑΤΑ. ΠΡΟΓΡΑΜΜΑ 1 ΕΞΗΓΗΣΤΕ ΤΙ ΕΞΟΔΟ ΠΑΡΑΓΕΙ ΤΟ ΠΑΡΑΚΑΤΩ ΠΡΟΓΡΑΜΜΑ #include int main() { char ch; int i; float fl; printf("dose.
Η ΓΛΩΣΣΑ C ΜΑΘΗΜΑ 2.
Υποθετικός τελεστής Ο υποθετικός τελεστής (?:) αποτελείται από δύο σύμβολα. Ανήκει στην κατηγορία των τελεστών που αποτελούνται από συνδυασμό συμβόλων.
Ολυμπιάδα Πληροφορικής
ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΙΑΔΙΚΑΣΤΙΚΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ – ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ.
ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ
Μεταβλητές – εντολές εκχώρησης- δομή ακολουθίας
Ενότητα Α.4. Δομημένος Προγραμματισμός
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Αρχεία.
Κεφάλαιο 10 – Υποπρογράμματα
ΛΟΓ102: Τεχνολογία Λογισμικού Ι Διδάσκων: Νίκος Παπασπύρου 1Νίκος ΠαπασπύρουΛΟΓ102:
ΛΟΓ102: Τεχνολογία Λογισμικού Ι Διδάσκων: Νίκος Παπασπύρου 1Νίκος ΠαπασπύρουΛΟΓ102:
ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Κλάσεις και Αντικείμενα Αναφορές.
2/28/00epl-1311 Παραδειγματα Aλγοριθμων Αριθμος λεξεων που διαβαστηκαν απο εισοδο Εκτυπωση περιφερειας τετραγωνων με * Υπολογισμος exp(x,n) = 1 + x/1!
ΗΥ 150 – Προγραμματισμός Ξενοφών Ζαμπούλης ΗΥ -150 Προγραμματισμός Αρχεία.
ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΕΣ ΤΕΧΝΙΚΕΣ Διδάσκοντες:Γιάννης Μαΐστρος Στάθης Ζάχος Νίκος Παπασπύρου
ΗΥ150 – ΠρογραμματισμόςΞ. Ζαμπούλης ΗΥ-150 Προγραμματισμός Αρχεία.
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Αλφαριθμητικά (Strings)
Βασικά στοιχεία της Java
ΗΥ150 – ΠρογραμματισμόςΚώστας Παναγιωτάκης ΗΥ-150 Προγραμματισμός Τύποι Μεταβλητών Τελεστές Βασική Είσοδος/Έξοδος.
ΚΕΦΑΛΑΙΟ Το αλφάβητο της ΓΛΩΣΣΑΣ
Τεχνολογικό Εκπαιδευτικό Ίδρυμα Θεσσαλίας Προγραμματισμός ΗΥ Ενότητα 2: Συναρτήσεις Εισόδου ⁄ Εξόδου. Διδάσκων: Ηλίας Κ Σάββας, Αναπληρωτής Καθηγητής.
Τεχνολογικό Εκπαιδευτικό Ίδρυμα Θεσσαλίας Προγραμματισμός ΗΥ Ενότητα 4: Επαναληπτικές δομές. Διδάσκων: Ηλίας Κ Σάββας, Αναπληρωτής Καθηγητής. Τμήμα Μηχανικών.
Πίνακες στην JAVA ΕΡΓΑΣΤΗΡΙΟ AΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΗΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ (Διαφάνειες: ΧΟΧΟΛΗΣ ΔΙΟΝΥΣΙΟΣ Προσαρμογή 2014: Κώστας Στάμος)
Τεχνολογία και Προγραμματισμός Υπολογιστών Ενότητα 5: Τύπος πίνακα,Μεταβλητές με δείκτη, Πολυδιάστατοι πίνακες Επίκουρος Καθηγητής Χρήστος Μακρής Τμήμα.
ΜΕΤΑΒΛΗΤΕΣ-ΣΤΑΘΕΡΕΣ -ΕΚΦΡΑΣΕΙΣ
Προτάσεις, εκφράσεις, τελεστές Βασικά στοιχεία ελέγχου προγράμματος
Επανάληψη.
Δεδομένα, μεταβλητές, υπολογισμοί
ΑΛΓΟΡΙΘΜΟΣ ΠΡΟΒΛΗΜΑ ΑΛΓΟΡΙΘΜΟΣ ΛΥΣΗ
Συναρτήσεις.
Δείκτες Προγραμματισμός Ι
Δομές.
Πίνακες Προγραμματισμός Ι
ΤΕΧΝΙΚΕΣ Αντικειμενοστραφουσ προγραμματισμου
Ενισχυτική διδασκαλία
ΕΝΤΟΛΕΣ ΕΠΙΛΟΓΗΣ Η εντολή if if ( παράσταση) εντολή επόμενη εντολή.
Αρχεσ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Η/Υ ΤΑξη Β΄
for (παράσταση_1; παράσταση_2; παράσταση_3)
Αρχεσ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Η/Υ ΤΑξη Β΄
Τύποι Μεταβλητών.
ΔΟΜΕΣ ΕΛΕΓΧΟΥ(if-else, switch) και Λογικοί τελεστές / παραστάσεις
Τεχνολογία και Προγραμματισμός Υπολογιστών
ΣΥΝΑΡΤΗΣΕΙΣ (Functions)
Τύποι Μεταβλητών Τελεστές Βασική Είσοδος/Έξοδος
Εισαγωγή στον Προγ/μό Υπολογιστών
Εντολές και δομές αλγορίθμου
Ανάπτυξη Εφαρμογών σε Προγραμματιστικό Περιβάλλον ΑΕΠΠ
ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΕΠΙΣΤΗΜΗ ΤΩΝ Η/Υ
ΕΚΦΡΑΣΕΙΣ, ΑΝΑΜΟΝΕΣ (DELAYS), ΗΧΟΙ
Λήψη Αποφάσεων και Συναρτήσεις Ελέγχου
ΑΣΚΗΣΕΙΣ.
Μεταγράφημα παρουσίασης:

Χαρακτήρες και συμβολοσειρές

Ο τύπος δεδομένων char Ξεχωριστός τύπος δεδομένων στη C για αποθήκευση δεδομένων τύπου χαρακτήρα Μπορούμε να αναθέσουμε σταθερές τύπου χαρακτήρα, στις οποίες συμπεριλαμβάνονται ακολουθίες διαφυγής Μπορούμε να τυπώσουμε τις μεταβλητές με την printf

Ο τύπος δεδομένων char char a, b, c; char d = 'A'; char es1 = '\a', es2 = '\t', es3 = '\n'; c = '!'; printf("Μεταβλητή c = %c\n", c); printf("Μεταβλητή d = %c\n", d); printf("%cΔοκιμή%cακολουθιών%cδιαφυγής\n", es1, es2, es3);

Ο τύπος δεδομένων char 1 2 3 4 5 6 7 8 9 40 ( ) * + , - . / 50 : ; 60 Στην πραγματικότητα: αριθμητικός τύπος δεδομένων καταλαμβάνει 1 byte αποθηκεύει την αριθμητική αντιστοιχία του κάθε χαρακτήρα βάσει του κώδικα ASCII 1 2 3 4 5 6 7 8 9 40 ( ) * + , - . / 50 : ; 60 < = > ? @ A B C D E

Ο τύπος δεδομένων char Ως αριθμητικός τύπος δεδομένων ο τύπος «char» επιδέχεται: ανάθεση τιμής τύπου ακεραίου όλες τις αριθμητικές πράξεις char ch = 66; ch = 66; /* B */ printf("ch = %c\n", ch); ch++; /* C */ ch = ch + 32; /* c */

Χαρακτήρας ή αριθμός; Εξαρτάται από το πώς τον χρησιμοποιούμε! #include <stdio.h> int main(void) { char c = 'A'; printf("Το c είναι ο χαρακτήρας %c\n", c); printf("Το c είναι ο αριθμός %d\n", c); return 0; }

Χαρακτήρας ή αριθμός; #include <stdio.h> int main(void) { char c; for (c = 'A'; c <= 'Z'; c++) { printf("%d --> %c\n", c, c); } return 0;

Προσοχή στα όρια Ο τύπος char μπορεί να αποθηκεύσει τιμές: μεταξύ –128 και 127, αν ο εξ ορισμού τύπος χαρακτήρων του μεταγλωττιστή είναι προσημασμένος μεταξύ 0 και 255, αν ο εξ ορισμού τύπος χαρακτήρων του μεταγλωττιστή είναι μη προσημασμένος Σκόπιμο είναι να χρησιμοποιούμε τους προσδιοριστές signed και unsigned

Προσοχή επίσης: Μην χρησιμοποιείται διπλά εισαγωγικά στις σταθερές τύπου «char» char a = "A";  char a = "A";  Για χαρακτήρες πέρα από τους Αγγλικούς, ψηφία και τα σημεία στίξης, χρησιμοποιείστε τύπο unsigned char Για χαρακτήρες πέρα από τους Αγγλικούς, ψηφία και τα σημεία στίξης, χρησιμοποιείστε τύπο unsigned char char a = 'γ';  unsigned char a = 'γ'; 

Συναρτήσεις της βιβλιοθήκης χαρακτήρων #include <ctype.h> int isalpha(int c)  TRUE, αν το c είναι γράμμα int isdigit(int c)  TRUE, αν το c είναι ψηφίο int isalnum(int c)  TRUE, αν το c είναι γράμμα ή ψηφίο int isxdigit(int c)  TRUE, αν το c είναι δεκαεξαδικό ψηφίο int iscntrl(int c)  TRUE, αν το c είναι χαρακτήρας ελέγχου int isgraph(int c)  TRUE, αν το c είναι χαρακτ. γραφικών int isprint(int c)  TRUE, αν το c είναι εκτυπώσιμος

Συναρτήσεις της βιβλιοθήκης χαρακτήρων int ispunct(int c)  TRUE αν το είναι σημείο στίξης int isspace(int c)  TRUE αν το c είναι χαρακτήρας διαστήματος (' ', '\t', '\n', '\r', '\f', '\v') int islower(int c)  TRUE αν το c είναι πεζός χαρακτήρας int isupper(int c)  TRUE αν το c είναι κεφαλαίος χαρακτήρας int tolower(int c)  Αν ο χαρακτήρας είναι κεφαλαίος επιστρέφει τον αντίστοιχο πεζό, αν όχι τον ίδιο τον χαρακτήρα int toupper(int c)  Αν ο χαρακτήρας είναι πεζός επιστρέφει τον αντίστοιχο κεφαλαίο, αν όχι τον ίδιο τον χαρακτήρα Οι συναρτήσεις isupper, islower, toupper και tolower ΔΕΝ είναι βέβαιο ότι λειτουργούν σωστά στα Ελληνικά

Είσοδος-έξοδος χαρακτήρων Χρησιμοποιούμε κυρίως τις συναρτήσεις βιβλιοθήκης που ορίζονται στο αρχείο ενσωμάτωσης stdio.h Είσοδος: getchar(), scanf() Έξοδος: putchar(), printf()

getchar(), putchar() int getchar(void); int putchar(int c);

getchar(), putchar() #include <stdio.h> #include <ctype.h> int main(void) { int c; c = getchar(); while (c != '\n') { putchar(toupper(c)); } return 0; $ gcc -o toupper toupper.c $ ./toupper abcd 0987 ABCD ΓγΨψΔδ ABCD 0987 ABCD ΓγΨψΔδ

scanf(), printf() scanf() printf() γενική συνάρτηση ανάγνωσης δεδομένων printf() γενική συνάρτηση εκτύπωσης δεδομένων Και στις δύο θα πρέπει να χρησιμοποιήσουμε ως προσδιοριστή μετατροπής το %c scanf("%c", &c); printf("%c", c);

scanf(), printf() #include <stdio.h> #include <ctype.h> int main(void) { char c; scanf("%c", &c); while (c != '\n') { printf("%c", toupper(c)); } return 0; $ gcc -o toupper toupper.c $ ./toupper.exe abcd 0987 ABCD ΓγΨψΔδ ABCD 0987 ABCD ΓγΨψΔδ

Παράδειγμα while ((c = getchar()) != '\n') { #include <stdio.h> #include <ctype.h> int main(void) { int c; int charCnt [4] = {0, 0, 0, 0}; while ((c = getchar()) != '\n') { if (islower(c)) charCnt[0]++; else if (isupper(c)) charCnt[1]++; else if (isdigit(c)) charCnt[2]++; else charCnt[3]++; } printf("%d small, %d caps, %d digits, %d other\n", charCnt[0], charCnt[1], charCnt[2], charCnt[3]);

Παράδειγμα while ((c = getchar()) != '\n') { #define SMALL 0 #define CAPS 1 #define DIGIT 2 #define OTHER 3 int main(void) { int c; int charCnt [4] = {0, 0, 0, 0}; while ((c = getchar()) != '\n') { switch (c) { case islower(c): charCnt[SMALL]++; break; case isupper(c): charCnt[CAPS]++; break; default: charCnt[OTHER]++; break; case isdigit(c): charCnt[DIGIT]++; break; } printf("%d small, %d caps, %d digits, %d other\n", charCnt[SMALL], charCnt[CAPS], charCnt[DIGIT], charCnt[OTHER]);

Συμβολοσειρές Οι μεταβλητές τύπου char αποθηκεύουν έναν μόνο χαρακτήρα Στα προγράμματά μας χρειαζόμαστε για πολλούς λόγους ακολουθίες χαρακτήρων π.χ. για μηνύματα («Δώστε το πλήθος των στοιχείων») για αποθήκευση τιμών (επώνυμο προσώπου, διεύθυνση, όνομα αρχείου)

Ο τύπος της συμβολοσειράς Σε αντίθεση με άλλες γλώσσες (Pascal, Basic) η C δεν έχει ειδικό τύπο για ακολουθίες χαρακτήρων (συμβολοσειρές) Στη C για αποθήκευση και χειρισμό συμβολοσειρών χρησιμοποιούνται πίνακες χαρακτήρων char surname[20]; char filename[256]; char streetName[32];

Μέγεθος πινάκων Για να αποθηκεύσουμε μία συμβολοσειρά με μήκος που μπορεί να φτάσει μέχρι Ν χαρακτήρες θα πρέπει να χρησιμοποιήσουμε έναν πίνακα Ν+1 χαρακτήρων "Αμόλυβδη"  char[9] "Σούπερ"  char[7] "Αμόλυβδη +"  char[11] Για να φυλάξουμε μία από αυτές τις τιμές (χωρίς εκ των προτέρων να ξέρουμε ποια) θα χρησιμοποιήσουμε τον μεγαλύτερο πίνακα

Τι συμβαίνει με τον επιπλέον χαρακτήρα; Στη γλώσσα C το τέλος μίας συμβολοσειράς υποδεικνύεται με τον χαρακτήρα \0 ΕΡΓΑΣΤΗΡΙΟ UNIX Ε Ρ Γ Α Σ Τ Η Ι Ο U N I X \0 Η συμβολοσειρά τελειώνει στον χαρακτήρα '\0', ανεξάρτητα αν ο πίνακας έχει δηλωθεί με μεγαλύτερο μήκος

Απόδοση αρχικών τιμών σε πίνακες χαρακτήρων Κανονική απόδοση αρχικής τιμής σε πίνακα char city[20] = {'T', 'R', 'I', 'P', 'O', 'L', 'I', '\0'}; char country[] = {'G', 'R', 'E', 'E', 'C', 'E', '\0'}; unsigned char hour[] = {'0', '9', ':', '0', '0', ' ', 'Π', 'Μ', '\0'}; Εναλλακτικά, χρήση των διπλών εισαγωγικών: char city[20] = "TRIPOLI"; char country[] = "GREECE"; unsigned char hour[] = "09:00 ΠΜ"; Αν χρησιμοποιούμε διπλά εισαγωγικά, το '\0' εισάγεται αυτόματα από τον μεταγλωττιστή

Tο '\0' είναι απαραίτητο! #include <stdio.h> int main(void) { long int a1 = 0x0000524f; long int b1 = 0x52524520; char aString[] = {'L', 'I', 'S', 'T'}; long int a2 = 0x52524520; long int b2 = 0x0000524f; printf("aString = %s\n", aString); return 0; } $ gcc -o b0 b0.c $ ./b0 LIST ERROR

Tο '\0' είναι απαραίτητο! #include <stdio.h> int main(void) { char aString[] = "Hasta la vista!"; printf("aString = %s\n", aString); aString[8] = '\0'; aString[5] = '\0'; aString[8] = '@'; aString[5] = '?'; return 0; } $ gcc -o terminator terminator.c $ ./terminator aString = Hasta la vista! aString = Hasta la aString = Hasta aString = Hasta?la@vista!

Συμβολοσειρές και δείκτες Οι συμβολοσειρές είναι πίνακες χαρακτήρων Ο κάθε πίνακας στη C είναι (σχεδόν) ισοδύναμος με ένα δείκτη στο πρώτο στοιχείο του … άρα κάθε συμβολοσειρά είναι (σχεδόν) ισοδύναμη με έναν δείκτη στον πρώτο χαρακτήρα της

Παράδειγμα – Εύρεση μήκους συμβολοσειράς #include <stdio.h> int main(void) { char aString[] = "This is a string"; int index, length; for (index = 0, length = 0; aString[index] != '\0'; index++) length++; printf("Το μήκος της συμβολοσειράς %s είναι %d\n", aString, length); return 0; }

Παράδειγμα – Εύρεση μήκους συμβολοσειράς #include <stdio.h> int main(void) { char aString[] = "This is a string"; int length; char *s; for (s = aString, length = 0; *s != '\0'; s++) length++; printf("Το μήκος της συμβολοσειράς %s είναι %d\n", aString, length); return 0; }

Παράδειγμα – Εύρεση μήκους συμβολοσειράς #include <stdio.h> int main(void) { char aString[] = "This is a string"; char *s; for (s = aString; *s != '\0'; s++) ; printf("Το μήκος της συμβολοσειράς %s είναι %d\n", aString, s - aString); return 0; }

Δείκτης ή πίνακας; char aString[18] = "I am a string"; char bString[] = "I am a string too"; char *cString = "I am yet another string"; Ποια μορφή θα χρησιμοποιήσουμε στο πρόγραμμά μας;

Δείκτης ή πίνακας; char aString[18] = "I am a string"; Ορίζουμε ρητώς το πλήθος χαρακτήρων – μπορούμε να δεσμεύσουμε περισσότερες θέσεις απ' ότι έχει η αρχική τιμή Το όνομα aString θα αναφέρεται πάντα στην ίδια περιοχή μνήμης Μπορούμε να αλλάξουμε τους χαρακτήρες που περιέχονται στη συμβολοσειρά aString[5] = 'A';

Δείκτης ή πίνακας; char bString[] = "I am a string too"; Δεν ορίζουμε ρητώς το πλήθος χαρακτήρων –δεσμεύουμε ακριβώς τόσες θέσεις όσες έχει η αρχική τιμή Το όνομα bString θα αναφέρεται πάντα στην ίδια περιοχή μνήμης Μπορούμε να αλλάξουμε τους χαρακτήρες που περιέχονται στη συμβολοσειρά bString[5] = 'A';

Δείκτης ή πίνακας; char *cString = "I am yet another string"; Το όνομα aString ΔΕΝ αναφέρεται πάντα στην ίδια περιοχή μνήμης – μπορούμε να το αλλάξουμε με μία ανάθεση cString = "τώρα δείχνω αλλού!"; cString = aString; Μετά από μία τέτοια ανάθεση, η αρχική συμβολοσειρά δεν είναι προσβάσιμη! ΔΕΝ ΕΙΝΑΙ ΒΕΒΑΙΟ ΟΤΙ μπορούμε να αλλάξουμε τους χαρακτήρες που περιέχονται στη συμβολοσειρά cString[5] = 'A'; Πιθανό σφάλμα κατά την εκτέλεση!

Συμβολοσειρές ως παράμετροι συναρτήσεων #include <stdio.h> int stringLength(char str[]) { char *s; for (s = str; *s != '\0'; s++) ; return s – str; } int main(void) { char s1[] = "Hello", s2[] = "good morning"; printf("Length of s1 = %d\n", stringLength(s1)); printf("Length of s2 = %d\n", stringLength(s2)); return 0; $ gcc -o stringlength stringlength.c $ ./stringlength Length of s1 = 5 Length of s2 = 12

Συμβολοσειρές ως παράμετροι συναρτήσεων #include <stdio.h> int stringLength(char *str) { char *s; for (s = str; *s != '\0'; s++) ; return s – str; } int main(void) { char s1[] = "Hello", s2[] = "good morning"; printf("Length of s1 = %d\n", stringLength(s1)); printf("Length of s2 = %d\n", stringLength(s2)); return 0; $ gcc -o stringlength stringlength.c $ ./stringlength Length of s1 = 5 Length of s2 = 12

Σύγκριση συμβολοσειρών #include <stdio.h> int main(void) { char str1[] = "Hello", str2[] = "Hello"; if (str1 == str2) printf("Equal\n"); else printf("Not equal\n"); return 0; } $ gcc -o compare compare.c $ ./compare Not equal

Σύγκριση συμβολοσειρών Η συμβολοσειρά είναι πίνακας χαρακτήρων Η C ΔΕΝ συγκρίνει πίνακες με μία μόνο εντολή Η έκφραση str1 == str2 μεταφράζεται ως: αν η διεύθυνση στη μνήμη του πρώτου στοιχείου του πίνακα str1 είναι ίση με τη διεύθυνση στη μνήμη του πρώτου στοιχείου του πίνακα str2 Η σύγκριση πρέπει να γίνει στοιχείο προς στοιχείο

Σύγκριση συμβολοσειρών #include <stdio.h> int main(void) { char str1[] = "Hello", str2[] = "Hello"; int i1, i2, equal; for (i1 = 0, i2 = 0, equal = 1; str1[i1] != '\0' && str2[i2] != '\0' && equal == 1; i1++, i2++) { if (str1[i1] != str2[i2]) equal = 0; } if ((str1[i1] != '\0') || (str2[i2] != '\0')) printf("Αποτέλεσμα σύγκρισης: %d\n", equal); return 0;

Σύγκριση συμβολοσειρών #include <stdio.h> int compareStrings(char *s1, char *s2) { while ((*s1 != '\0') && (*s2 != '\0')) { if (*s1 != *s2) return 0; s1++; s2++; } if ((*s1 == '\0') && (*s2 == '\0')) return 1; else int main(void) { char s1[] = "Hello", s2[] = "Hello"; printf("Αποτέλεσμα: %d\n", compareStrings(s1, s2));

Ανάθεση τιμής και συμβολοσειρές Αν a και b δύο ακέραιες μεταβλητές, αναθέτουμε στο a την τιμή του b γράφοντας: a = b; Μπορούμε να κάνουμε το ίδιο με συμβολοσειρές;

Ανάθεση τιμής και συμβολοσειρές char s_A1[10] = "String A1", s_A2[10] = "String A2"; char s_B1[] = "String B1", s_B2[] = "String B2"; char *s_C1 = "String C1", *s_C2 = "String C2"; s_A2 s_B2 s_C2 s_A1 =  s_B1 = s_C1 = 

Ανάθεση τιμής και συμβολοσειρές "s_C1 = s_A1": Συντακτικώς σωστό αλλά... s_A1 S t r i n g A 2 \0 ΠΡΙΝ s_C1 S t r i n g C 1 \0 s_A1 S t r i n g A 2 \0 ΜΕΤΑ s_C1 S t r i n g C 1 \0

Ανάθεση τιμής και συμβολοσειρές "s_C1 = s_A1": Συντακτικώς σωστό αλλά... χάνουμε την αναφορά στις θέσεις μνήμης όπου αρχικά έδειχνε η s_C1 αν αλλάξουμε κάποιον χαρακτήρα της μίας συμβολοσειράς, τροποποιείται ταυτόχρονα και η άλλη Πρέπει να αντιγράφονται τα στοιχεία της συμβολοσειράς, όχι να αλλάζουμε τον δείκτη!

Ανάθεση τιμής και συμβολοσειρές #include <stdio.h> int main(void) { char s1[30] = "String ONE"; char s2[30] = "String TWO"; int index; for (index = 0; s1[index] != '\0'; index++) s2[index] = s1[index]; s2[index] = '\0'; puts(s2); return 0; }

Συνένωση συμβολοσειρών "str1" "str2"  "str1str2" #include <stdio.h> int main(void) { char s1[30] = "String ONE"; char s2[30] = "String TWO"; char s3[60]; int index, index2; for (index = 0; s1[index] != '\0'; index++) s3[index] = s1[index]; for (index2 = 0; s2[index2] != '\0'; index2++) s3[index++] = s2[index2]; s3[index] = '\0'; puts(s3); return 0; }

Είσοδος-έξοδος συμβολοσειρών Για την είσοδο-έξοδο συμβολοσειρών χρησιμοποιούνται οι συναρτήσεις βιβλιοθήκης που ορίζονται στο αρχείο ενσωμάτωσης stdio.h Είσοδος: gets(), scanf(), fgets() Έξοδος: puts(), printf()

gets(), puts() char *gets(char *s) int puts(char *s) Τυπώνει τους χαρακτήρες της συμβολοσειράς στην έξοδο. Μετά τυπώνει και έναν χαρακτήρα αλλαγής γραμμής.

gets(), puts() H gets αποθηκεύει Ο χρήστης γράφει #include <stdio.h> int main(void) { char s[20]; gets(s); puts(s); return 0; } Ο χρήστης γράφει H A S T _ L V I \n H A S T _ L V I \0 H gets αποθηκεύει

scanf, printf scanf() printf() γενική συνάρτηση ανάγνωσης δεδομένων printf() γενική συνάρτηση εκτύπωσης δεδομένων Και στις δύο περιπτώσεις χρησιμοποιούμε τον προσδιοριστή μετατροπής %s

scanf() #include <stdio.h> int main(void) { char s[20]; scanf("%s", s); return 0; } Διαβάζει χαρακτήρες από την είσοδο (κανονικά: πληκτρολόγιο) και τους αποθηκεύει στη συμβολοσειρά. Αρχικοί "κενοί" χαρακτήρες της εισόδου (isspace(c) είναι αληθές) αγνοούνται. Η διαδικασία σταματά στον πρώτο "κενό" χαρακτήρα. Στο τέλος αποθηκεύει και τον χαρακτήρα '\0'.

scanf() H scanf αποθηκεύει Ο χρήστης γράφει #include <stdio.h> int main(void) { char s[20]; scanf("%s", s); puts(s); return 0; } Ο χρήστης γράφει _ H A S T L V I \n H A S T \0 H scanf αποθηκεύει

scanf() Οι χαρακτήρες που τυχόν δεν θα διαβαστούν από τη scanf μένουν διαθέσιμοι για την επόμενη ανάγνωση (scanf, getchar, κ.λπ.) #include <stdio.h> int main(void) { char name[20], surname[20]; printf("Δώστε όνομα και επώνυμο: "); scanf("%s%s", name, surname); printf("Ονομα: %s\nΕπώνυμο: %s\n", name, surname); return 0; }

scanf H scanf αποθηκεύει Ο χρήστης γράφει H scanf αποθηκεύει Μ Α Ρ Κ Ο Σ _ Π Τ Η \n name: Μ Α Ρ Κ Ο Σ \0 surname: Μ Π Ο Τ Σ Α Ρ Η \0 H scanf αποθηκεύει Ο χρήστης γράφει Π Α Λ Ι Ω Ν \n Τ Ρ _ Γ Ε Μ Ο Σ name: Π Α Λ Ι Ω Ν \0 surname: Π Α Τ Ρ Ω Ν \0 H scanf αποθηκεύει

scanf() Καθορισμός μεγέθους για τον προσδιοριστή μετατροπής %s scanf("%20s", s) Διάβασε το πολύ 20 χαρακτήρες από την είσοδο και αποθήκευσέ τους στη μεταβλητή s Αρχικοί "κενοί" χαρακτήρες και πάλι αγνοούνται Αν βρεθεί κενός χαρακτήρας πριν τον 20ο, η ανάγνωση και αποθήκευση τερματίζεται εκεί. Μετά τους χαρακτήρες που θα διαβαστούν και θα αποθηκευθούν, θα αποθηκευθεί και ο χαρακτήρας \0

scanf() H scanf αποθηκεύει Ο χρήστης γράφει H scanf αποθηκεύει scanf("%19s", s); Ο χρήστης γράφει Σ Κ Ο Υ Λ Η Μ Ρ Γ Τ Π Α \n s: Σ Κ Ο Υ Λ Η Μ Ρ Γ Τ \0 H scanf αποθηκεύει Ο χρήστης γράφει Α Υ Τ Ο Κ Ι Ν Η Δ Ρ Μ Σ _ Ε 5 \n s: Α Υ Τ Ο Κ Ι Ν Η Δ Ρ Μ Σ \0 H scanf αποθηκεύει

scanf() Χρήση του προσδιοριστή μετατροπής %c με καθορισμό μεγέθους για ανάγνωση συμβολοσειράς καθορισμένου μήκους scanf("%20c", s) Διάβασε ακριβώς 20 χαρακτήρες από την είσοδο και αποθήκευσέ τους στη μεταβλητή s Αρχικοί "κενοί" χαρακτήρες ΔΕΝ αγνοούνται, αλλά αποθηκεύονται κανονικά στη μεταβλητή Η ανάγνωση ΔΕΝ τερματίζεται στον πρώτο "κενό" χαρακτήρα, παρά μόνο στον 20ο Μετά τους χαρακτήρες που θα διαβαστούν και θα αποθηκευθούν ΔΕΝ θα αποθηκευθεί ο χαρακτήρας \0

scanf() H scanf αποθηκεύει Ο χρήστης γράφει H scanf αποθηκεύει scanf("%20c", s); Ο χρήστης γράφει Σ Κ Ο Υ Λ Η Μ Ρ Γ Τ Π Α \n s: Σ Κ Ο Υ Λ Η Μ Ρ Γ Τ Π H scanf αποθηκεύει Ο χρήστης γράφει Α Υ Τ Ο Κ Ι Ν Η Δ Ρ Μ Σ \n Ε 5 s: Α Υ Τ Ο Κ Ι Ν Η Δ Ρ Μ Σ \n Ε 5 H scanf αποθηκεύει

scanf() Μπορούμε με μία εντολή scanf να διαβάσουμε συμβολοσειρές, αριθμητικά δεδομένα και χαρακτήρες #include <stdio.h> int main(void) { char licPlateLetters[4]; int licPlaceNumber; printf("Δώστε τον αριθμό κυκλοφορίας (π.χ. ΔΟΚ 2021): "); scanf("%3s%d", licPlateLetters, &licPlaceNumber); printf("Γράμματα: %s\nΑριθμός: %d\n", licPlateLetters, licPlaceNumber); return 0; }

Περισσότερη Ασφάλεια fgets(str, sizeof(str), stdin) scanf(“%ns”, str) όπου n το μέγιστο πλήθος χαρακτήρων που θα διαβαστούν

printf() Στη βασική της μορφή με τον προσδιοριστή μετατροπής %s, απλά τυπώνει τη συμβολοσειρά, η οποία πρέπει να τερματίζεται με \0 char s[] = "I am a string"; printf("%s\n", s);

printf() Μπορούμε να καθορίσουμε το ελάχιστο μήκος που θα καταλάβει η συμβολοσειρά κατά την εκτύπωση printf("%20s\n", s); Η printf, αν το μήκος της συμβολοσειράς είναι μικρότερο από το ελάχιστο μήκος, θα προσθέσει κενά πριν τη συμβολοσειρά

printf() #include <stdio.h> int main(void) { char *s0 = "Αμόλυβδη"; char *s1 = "Σούπερ"; char *s2 = "Αμόλυβδη +"; double prices[3] = {0.71, 0.76, 0.87}; printf("%s %f\n", s0, prices[0]); printf("%s %f\n", s1, prices[1]); printf("%s %f\n", s2, prices[2]); } Αμόλυβδη 0.710000 Σούπερ 0.760000 Αμόλυβδη + 0.870000

printf() #include <stdio.h> int main(void) { char *s0 = "Αμόλυβδη"; char *s1 = "Σούπερ"; char *s2 = "Αμόλυβδη +"; double prices[3] = {0.71, 0.76, 0.87}; printf("%15s %f\n", s0, prices[0]); printf("%15s %f\n", s1, prices[1]); printf("%15s %f\n", s2, prices[2]); } Αμόλυβδη 0.710000 Σούπερ 0.760000 Αμόλυβδη + 0.870000

printf() Αν πριν τον καθορισμό ελάχιστου μήκους παραθέσουμε τον χαρακτήρα "–" τα τυχόν κενά προστίθενται στο τέλος της συμβολοσειράς printf("%-15s %f\n", s0, prices[0]); printf("%-15s %f\n", s1, prices[1]); printf("%-15s %f\n", s2, prices[2]); Αμόλυβδη 0.710000 Σούπερ 0.760000 Αμόλυβδη + 0.870000

printf() Μπορούμε να καθορίσουμε μέγιστο πλήθος χαρακτήρων που θα εμφανιστούν printf("%.20s", s); εμφάνισε το πολύ 20 χαρακτήρες από τη συμβολοσειρά s. Αν έχει παραπάνω, οι πέραν του 20ου αγνοούνται printf("%-15.20s", s) εμφάνισε τη συμβολοσειρά s. Αν έχει λιγότερους από 15 χαρακτήρες, συμπλήρωσε κενά στο τέλος της, μέχρι να συμπληρωθούν 15. Αν έχει περισσότερους από 20, εμφάνισε μόνο τους 20 πρώτους

Ερωτήσεις - Ασκήσεις Έστω η δήλωση char *str = "I am a string"; Ποια η τιμή των εξής εκφράσεων: str[0] *str str[8] str[22] *str + 11 str Γράψτε ένα πρόγραμμα που θα διαβάζει αριθμητικές τιμές από τον χρήστη και θα τυπώνει τους αντίστοιχους χαρακτήρες του πίνακα ASCII

Ερωτήσεις - Ασκήσεις Βρείτε τα λάθη (αν υπάρχουν) στις ακόλουθες γραμμές char string1[8] = "I am a string"; char string2[]; char ch = "\n"; char string3 = "Hello"; char string4[] = "I am a String"; char *string5 = 'A'; char *string6; string4 = string1; string3 = 'A'; string6 = string4 + 2; Γράψτε την ανάθεση και τη συνένωση για συμβολοσειρές χρησιμοποιώντας δείκτες

Ερωτήσεις - Ασκήσεις Γράψτε ένα πρόγραμμα που θα διαβάζει από τον χρήστη έναν ακέραιο x (0 <= x <= 80) και θα δημιουργεί σε μία μεταβλητή μία συμβολοσειρά με x αστερίσκους, την οποία και θα τυπώνει. π.χ. για είσοδο 7 δημιουργείται η συμβολοσειρά ******* Γράψτε μία συνάρτηση που θα συγκρίνει δύο συμβολοσειρές, θεωρώντας ότι πεζοί και κεφαλαίοι είναι ίσοι (οι συμβολοσειρές "AbCd" και "aBcD" θα αναφέρονται ως ίσες) Γράψτε μία συνάρτηση που θα δέχεται ως παραμέτρους δύο συμβολοσειρές και έναν ακέραιο n και θα συγκρίνει τους n πρώτους χαρακτήρες των συμβολοσειρών. Προβλέψτε την περίπτωση κάποια συμβολοσειρά να έχει λιγότερους από n χαρακτήρες