Δπαλάιεςε Αιθαξηζκεηηθέο εηξέο Υαξαθηήξσλ (Strings) (Γηάιεμε 2) Γηδάζθσλ: Γεκήηξεο Εετλαιηπνύξ 2-1
1) Strings ζηε C Έλα string είλαη κία αθνινπζία αιθαξηζκεηηθώλ ραξαθηήξσλ, ζεκείσλ ζηίμεο θηι. Π.ρ. Hello How are you? 121212 *Apple#123*% Σεκεξηλή Γηάιεμε: Φξήζε ηεο πην απιήο δνκήο δεδνκέλσλ: πίλαθαο 1. Δηζαγσγηθέο Έλλνηεο ζε Strings(Αξρηθνπνίεζε, Αλάγλσζε & Δθηύπσζε) 2. Πίλαθεο από Strings 3. Σπλαξηήζεηο Βηβιηνζήθεο <string.h> 4. Υινπνίεζε Σπλαξηήζεσλ Βηβιηνζήθεο 2-2
1) Strings ζηε C Έρνπκε ήδε ρξεζηκνπνηήζεη ζε δηάθνξεο πεξηπηώζεηο ηα strings π.ρ. printf( Hello ); Μέρξη ηώξα όκσο, δελ αλαθεξόκαζηαλ ζηα strings κε ηελ ρξήζε κεηαβιεηώλ. Σηελ C δελ ππάξρεη ν ηύπνο String (όπσο ην float, int θαη char), αιιά απηόο πινπνηείηαη σο πίλαθεο ραξαθηήξσλ H E L L O \0 Δπαλαιακβάλνπκε ηα strings γηαηί ζα καο δώζεη ηελ δπλαηόηεηα λα δνπιέςνπκε κε ηελ απινύζηεξε δνκή δεδνκέλσλ: ηνλ πίλαθα, αιιά θαη γηα ιόγνπο επαλάιεςεο 2-3
1.1) Αξρηθνπνίεζε string Οξηζκόο String Έλαο πίλαθαο από ραξαθηήξεο πνπ ηειεηώλεη κε ηνλ ραξαθηήξα NULL \0, π.ρ. Hello\0, Hi there\0, \0 (Πξνζνρή ην \0 δελ θαίλεηαη ζηελ νζόλε) Υπάξρνπλ δηάθνξνη ηξόπνη λα νξίζνπκε έλα String ζηελ C, αλάινγα κε ην αλ γλσξίδνπκε ην string πξνηνύ ηελ κεηαγιώηηηζε ή όρη. Α) Αξρηθνπνίεζε (γλσξίδνληαο εθ ησλ πξόηεξσλ ην String) char msg[ ]= Hello ; Γεκηνπξγεί απηόκαηα ην: H E L L O \0 2-4
1.1) Αξρηθνπνίεζε string σζηό char msg[6]; msg[0] = 'H'; msg[1] = 'e'; msg[2] = 'l'; msg[3] = 'l'; msg[4] = 'o'; msg[5] = '\0'; Λάζνο char msg[ ]={ H, e, l, l, o ; πλίζηαηαη απηόο ν νξηζκόο char msg[ ]= Hello αιιά ππάξρνπλ θαη άιινη ηξόπνη σζηό char msg[ ]={ H, e, l, l, o, \0 ; σζηό char msg[6]={ H, e, l, l, o, \0 ; σζηό αιιά ζπάηαιν char msg[40]= Hello Γελ δεζκεύνπκε αξθεηό ρώξν θαη δεκηνπξγείηαη buffer overflow Λάζνο char msg[5]={'h','e','l','l','o','\0'; Πίλαθαο ραξαθηήξσλ πνπ δελ ηειεηώλεη ζε \0. Δπνκέλσο δελ είλαη String Αλ θάπνηνο εθηειέζεη printf( %s, msg); Σόηε ζηελ νζόλε ζα δείμεη Hello??? 2-5
1.1) Αξρηθνπνίεζε string Αο δνύκε πσο κνηάδνπλ εηθνληθά νη αθόινπζνη νξηζκνί char msg[10]= Hello ; H E L L O \0 SIZE=10 Σν? είλαη απξνζδηόξηζηνο ραξαθηήξαο char msg[ ]= Hello ; H E L L O \0 SIZE=6 2-6
1.1) Ζ δηάθνξα char θαη string Αο δνύκε πσο κνηάδνπλ εηθνληθά νη αθόινπζνη νξηζκνί char c = H ; Ο ραξαθηήξαο H βξίζθεηαη θάπνπ ζηελ κλήκε??? H?? char c[ ]= H ; char H c[ ]= H ; \0 Σν String H βξίζθεηαη θάπνπ ζηελ κλήκε char c= H ; ΛΑΘΟ ζηελ κεηαγιώηηηζε 2-7
1.1) Αξρηθνπνίεζε string Δξώηεζε Τη γίλεηαη αλ δελ μέξνπκε ην String εθ ησλ πξόηεξσλ; Πόζν ρώξν πξέπεη λα δεζκεύζνπκε; Απάληεζε Αξθεηό γηα λα ρσξέζεη δηάθνξα δεδνκέλα εηζόδνπ πνπ πξόθεηηαη λα εηζάγνπκε. π.ρ. αλ πξόθεηηαη λα απνζεθεύζνπκε θάπνην όλνκα ηόηε 20 ραξαθηήξεο θαίλεηαη λα αξθνύλ. Σηελ πξαγκαηηθόηεηα ρξεζηκνπνηνύκε δπλακηθή δέζκεπζε κλήκεο, ε νπνία καο επηηξέπεη λα δεζκεύζνπκε ηνλ απαηηνύκελν ρώξν θαηά ηελ δηάξθεηα εθηέιεζεο ηνπ πξνγξάκκαηνο (ζα κηιήζνπκε γηα απηό ην ζέκα ζηελ ζπλέρεηα ηνπ καζήκαηνο)! Πξνηνύ δνύκε έλα παξάδεηγκα, αο δνύκε πσο δηαβάδνπκε strings από ηνλ ρξήζηε θαη πσο ηα εθηππώλνπκε. 2-8
1.2) Αλάγλσζε/Δθηύπσζε String scanf ( %s, name) ΠΡΟΟΥΗ: Γελ ρξεζηκνπνηείηε ην &, γηαηί ην name είλαη πίλαθαο. Θπκεζείηε όηη ζε άιινπο ηύπνπο δεδνκέλσλ ρξεζηκνπνηείηαη ην & π.ρ. scanf( %d, &a); Γηα εηζαγσγή ζπκβνινζεηξάο κε θελά ρξεζηκνπνηείηαη ε fgets(name, sizeof(name), stdin); ή #define MAX "50 scanf("%" MAX "[^\n]", name); printf ( %s,name) Γηα εθηύπσζε ζπκβνινζεηξώλ 2-9
1.2) Αλάγλσζε/Δθηύπσζε string #include <stdio.h> int main() { char name[20]; scanf("%s", name); printf("%s", name); return 0; M A R I A \0 Σν printf γλσξίδεη όηη ε εθηύπσζε πξέπεη λα γίλεη κέρξη ην \0 6.. 19 2-10
1.2) Αλάγλσζε/Δθηύπσζε string Πξόγξακκα πνπ πξνζζέηεη έλα «Α» ζηελ ζέζε 5 θαη ηεξκαηίδεη ην string #include <stdio.h> int main() { char name[20]; scanf("%s", name); name[5]= Α ; name[6]= \0 ; printf("%s", name); return 0; Πξίλ M A R I A \0 Μεηά M A R I A A 6.. 19 6.. 19 \0??? 2-11
Κνηλό Λάζνο (Αλάζεζε ζε String) Υπνζέζηε όηη έρνπκε ηελ πην θάησ δήισζε char name [50]; Γελ επηηξέπεηε λα αλαζέζνπκε έλα string από έλα άιιν (όπσο ζηνπο ππόινηπνπο ηύπνπο) Π.ρ. name= hydrogen ΛΑΘΟ (compile error) error: incompatible types in assignment name={ h, y, d, r, o, \0 ΛΑΘΟ (compile error) name[0]= h ; name[1]= y ;. ΟΡΘΟ Όκσο, ππάξρεη επθνιόηεξνο ηξόπνο ηνλ νπνίν ζα δνύκε ζε ιίγν (κε ρξήζε strcpy) 2-12
2) Πίλαθεο από Strings Δίπακε όηη ην String είλαη έλαο κνλνδηάζηαηνο πίλαθαο από ραξαθηήξεο πνπ ηειεηώλεη ζε \0. Μπνξνύκε λα έρνπκε πίλαθεο από Strings; ΝΑΙ Παξαδείγκαηα π.ρ. Λίζηα κε νλόκαηα, εκέξεο, θηι char names[num_students][name_len]; char weekdays[7][10]={ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday ; 6 0 M o n d a y \0 \0? \0?? 1 T u e s d a y \0?? 6 S u n d a y \0??? 2-13
3) Σπρλέο ιεηηνπξγίεο κε string Υπάξρνπλ θάπνηεο ιεηηνπξγίεο πνπ είλαη πνιύ ζπρλέο πάλσ ζε Strings. Παξαδείγκαηα Compare: Σύγθξηζε δπν strings Copy: Αληηγξαθή από έλα string ζε άιιν νιόθιεξν ή κέξνο ηνπ. Concat: ζύλδεζε δπν strings Substring: εύξεζε ζπκβνινζεηξάο ζε κηα κεγαιύηεξε αθνινπζία Η Βηβιηνζήθε <String.h> πεξηέρεη ζπλαξηήζεηο γηα όια ηα πην πάλσ. Γηα εμάζθεζε ζα πινπνηήζνπκε θάπνηεο από ηηο ζπλαξηήζεηο κόλνη καο 2-14
3) Ζ ζπλάξηεζε strcmp() Οη ζπγθξίζεηο γίλνληαη βάζε ηνπ πίλαθα ASCII 2-15
3) Ζ Βηβιηνζήθε string.h Τν αξρείν επηθεθαιίδα (header file), string.h παξέρεη ζπλαξηήζεηο γηα ρεηξηζκό strings Πεξηέρεη Γηάθνξεο Σπλαξηήζεηο, π.ρ., strlen(s), ππνινγίδεη ην κέγεζνο ηνπ string strcpy(s1,s2), αληηγξάθεη ην s2 ζην s1 strcat(s1,s2), πξνζζέηεη ην s2 ζην s1. strcmp(s1,s2), ζπγθξίλεη ην s1 κε s2 θαη επηζηξέθεη ζεηηθή ηηκή εάλ s1 κεγαιύηεξν (αιθαβεηηθά) από ην s2, κεδέλ αλ είλαη ίζα, θαη αξλεηηθή ηηκή εάλ s1 κηθξόηεξν από s2. (Η ζύγθξηζε γίλεηαη βάζε ηνπ πίλαθα ASCII) 2-16
3) Ζ ζπλάξηεζε strlen() H ζπλάξηεζε strlen κεηξά ην κέγεζνο ελόο String. π.ρ. char msg[10]= HELLO H E L L O \0 printf( %d, strlen(msg)); Δθηππώλεη: 5. Γειαδή ηνλ αξηζκό ησλ ραξαθηήξσλ έσο ην \0 Πξνζνρή!!! Tν strlen δελ καο ιέεη ην κέγηζην κέγεζνο ηνπ string. Απηό είλαη 10 ραξαθηήξεο θαη ην μέξνπκε πξηλ ην compile ή κε «printf("%ld", sizeof(msg));» 2-17
#include <stdio.h> #include <string.h> 3) Ζ ζπλάξηεζε strlen() int main() { char x[10] = "123456" ; printf("%d", strlen(x)); return 0; Σππώλεη 6 2-18
3) Ζ ζπλάξηεζε strlen() Ξέξνπκε όηη ε strlen είλαη έηνηκε ζπλάξηεζε. Γηα εμάζθεζε, ζα ηελ πινπνηήζνπκε κόλνη καο ΑΚΗΗ Γξάςεηε ηελ ζπλάξηεζε int mystrlen(char c[]) πνπ κέηξα ην κέγεζνο ελόο string. Ζ ζπλάξηεζε επηζηξέθεη ην κήθνο ηνπ string Tη ζα επηζηξέςεη? mystrlen( abc ) => 3 char x[10] = 123456 ; mystrlen(x); => 6 mystrlen( abc abc ) => 7 2-19
3) Ζ ζπλάξηεζε strlen() Αιγόξηζκνο Γηάβαζε ην string από ηελ αξρή κέρξη λα βξεηο ην \0. Σε θάζε βήκα αύμεζε θάπνην κεηξεηή θαηά 1. name M A R I A A 6.. 19 \0??? Δξώηεζε Γηαηί δελ κπνξνύκε λα πάκε θαηεπζείαλ ζην ηέινο ηνπ String (γηα λα βξνύκε θαηεπζείαλ ην κέγεζνο); 2-20
#include <stdio.h> int mystrlen (char s[]) { int i=0; while (s[i]!= '\0') i++; return i; int main() { char x[10] = "123456" ; printf("%d", mystrlen(x)); 3) Ζ ζπλάξηεζε strlen() 2-21
1) Ζ ζπλάξηεζε strcpy() H ζπλάξηεζε strcpy(ma, mb) αληηγξάθεη ην mb ζην ma Πξίλ π.ρ. ma?? mb H E L L O \0 int main() Μεηά { char ma[10]; ma char mb[10]="hello"; mb strcpy(ma,mb); printf("ma=%s and mb=%s", ma, mb); H E L L O \0 H E L L O \0 2-22
1) Υινπνίεζε ηεο strcpy() Υινπνηήζηε ηελ ζπλάξηεζε mystrcpy(char to[], char from[]) ε νπνία αληηγξάθεη ηo String b ζην String a Αιγόξηζκνο Γηα θάζε ζηνηρείν from[i] αληίγξαςε ην from[i] ζηελ ζέζε to[i], κέρξη λα θηάζεηο ζην \0. 2-23
1) Υινπνίεζε ηεο strcpy() #include <stdio.h> /* To string from αληηγξάθεηαη ζην to */ void mystrcpy(char to[ ], char from[ ]) { int i=0; while (from[i]!= '\0') { to[i] = from[i]; i++; to[i]='\0'; int main() { char ma[10]; char mb[10]="hello"; mystrcpy(ma,mb); printf("ma=%s and mb=%s", ma, mb); Πξίλ to?? from Μεηά H E L L O \0 H E L L O \0 to from H E L L O \0 2-24
2) Ζ ζπλάξηεζε strcat() H ζπλάξηεζε strcat(s1, s2) αληηγξάθεη ην s2 ζην ηέινο ηνπ s1 Πξίλ π.ρ. s1 H E L L O \0 s2 C A T \0?? int main() Μεηά { char ma[10]="hello"; s1 char mb[10]="cat"; s2 strcat(ma,mb); printf("ma=%s and mb=%s", ma, mb); H E L L O C C A T \0?? A T \0? 2-25
2) Υινπνίεζε strcat() Υινπνηήζηε ηελ ζπλάξηεζε void mystrcat(char s1[], char s2[]) ε νπνία πξνζζέηεη ηo string s2 ζην ηέινο ηνπ s1 Αιγόξηζκνο Βξεο ην \0 ζην s1 ζηελ ζέζε K. Αληίγξαςε θάζε s2[i], ζηελ αληίζηνηρε ζέζε s1[i+k]. Πξόζζεζε \0 ζην ηέινο ηνπ s1. 2-26
2) Υινπνίεζε strcat() έθδνζε 1 void mystrcat(char s1[], char s2[]) { int i=0, k=0; // Δύξεζε \0 ζην S1 while (s1[k]!= '\0') { k++; // Αληηγξαθή ηνηρείσλ while (s2[i]!= '\0') { s1[k+i]=s2[i]; i++; s1[k+i]= \0 ; Πξίλ s1 H E L L O \0 s2 Μεηά s1 s2 C A T \0?? H E L L O C C A T \0?? // Πξνζζήθε NULL ζην ηέινο ηνπ s1 θ A T \0? 2-27
2) Υινπνίεζε strcat() - έθδνζε 2 void mystrcat(char s1[], char s2[]) { int i=0, k=0; // Δύξεζε \0 ζην S1 k = strlen(s1); s2 Υξήζε strlen Πξίλ s1 H E L L O \0 Μεηά C A T \0?? // Αληηγξαθή ηνηρείσλ s1 H E L L O C while (s2[i]!= '\0') { s1[k+i]=s2[i]; i++; s2 C A T \0?? s1[k+i]= \0 ;// πξνζζήθε NULL ζην ηέινο ηνπ s1 θ A T \0? 2-28