MΑΘ 106/3122 Ξ. Ζαμπούλης ΜΑΘ 106/3122 Γλώσσα Προγραμματισμού Αλφαριθμητικά (Strings)
MΑΘ 106/3122 Ξ. Ζαμπούλης Standard library accessed by #include 2
MΑΘ 106/3122 Ξ. Ζαμπούλης 3 Χαρακτήρες Αναπαριστώνται από έναν δυαδικό αριθμό 8 δυαδικών ψηφίων (8 bits) (256 διαφορετικές τιμές) Η κωδικοποίησή τους έχει τυποποιηθεί με τον κώδικα ASCII Εκτός από γράμματα και ψηφία υπάρχουν και πολλοί ειδικοί χαρακτήρες Σταθερές χαρακτήρων – Η έκφραση 'z' είναι μια σταθερά και αντιστοιχεί σε έναν int με τα 8 τελευταία του bits ίσα με τον ASCII κωδικό του χαρακτήρα – 'z‘, ‘\t‘, ‘\n‘, κτλ
MΑΘ 106/3122 Ξ. Ζαμπούλης 4 Βασικά για τα Αλφαριθμητικά (strings) Μια σειρά από χαρακτήρες που αντιμετωπίζονται σαν ένα αντικείμενο – Γράμματα, αριθμοί, ειδικοί χαρακτήρες (*, /, $) και όλοι οι εκτυπώσιμοι χαρακτήρες – Τιμές εισάγονται μέσα σε διπλά εισαγωγικά "Hello" – Τα Strings είναι πάντα πίνακες από χαρακτήρες Ένα String είναι δείκτης στον 1 ο χαρακτήρα του πίνακα Τιμή του string είναι η διεύθυνση του 1 ου χαρακτήρα του πίνακα
MΑΘ 106/3122 Ξ. Ζαμπούλης 5 char vs. C string ‘A’ has data type char and is stored in 1 byte “A” is a C string of 2 characters and is stored in 2 bytes 5000 ‘A’ 6000 ‘A’ 6001 ‘\0’
MΑΘ 106/3122 Ξ. Ζαμπούλης 6 There is a difference between 'A' and "A". The first one is character A and the second is string A. Since strings are null terminated, "A" represents two characters, 'A' and '\0'. "Hello" represents six characters, 'H', 'e', 'l', 'l', 'o', and '\0'. To store 'A' we need only one memory cell of the type char, while to store "A", we need two memory cells of the type char, one for 'A' and the other for '\0'. To store the string "HELLO" in computer we need six memory cells of the type char. Consider the statement. char name[16]; Since C strings are null terminated and name has sixteen components, the largest string that can be stored in name is 15. If you store a string of length, say 10 in name, the first 11 components of name are used and the last 5 are left unused.
MΑΘ 106/3122 Ξ. Ζαμπούλης 7 Character Arrays strlen("hello, world"); /* string constant */ strlen(array); /* char array[100]; */ strlen(ptr); /* char *ptr; */ char pmessage[] = "now is the time"; /* an array */ char *amessage = "now is the time"; /* a pointer */
MΑΘ 106/3122 Ξ. Ζαμπούλης 8 char message[8]; // declaration allocates memory To the compiler, the value of the identifier message alone is the base address of the array. We say message is a pointer (because its value is an address). It “points” to a memory location. message [0] [1] [2] [3] [4] [5] [6] [7] ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ 6000
MΑΘ 106/3122 Ξ. Ζαμπούλης 9 Ποιά η σχέση με τη malloc? Η malloc δεσμεύει στατικά ποσά μνήμης και επιστρέφει τον pointer σε αυτά. Έτσι χρειαζόμαστε την ειδική εντολή (realloc) για να τα αυξομειώσουμε τα ποσά αυτά, – αφού τελικά όλα πρέπει να τα «εγκρίνει» το λειτουργικό σύστημα.
MΑΘ 106/3122 Ξ. Ζαμπούλης 10 Δηλώσεις Δηλώσεις αλφαριθμητικών – Σαν πίνακας από χαρακτήρες ή σαν δείκτης σε χαρακτήρα char * char color[] = "blue"; char *colorPtr = "blue"; – Κάθε string τελειώνει με '\0' και πρέπει να το λαμβάνουμε υπόψη στη δήλωση του πίνακα color has 5 elements
MΑΘ 106/3122 Ξ. Ζαμπούλης 11 string[0] = ‘J’ string[1] = ‘I’ string[2] = ‘b’ string[3] = ‘r’ string[4] = ‘a’ string[5] = ‘n’ string[6] = ’ ’ string[7] = ‘B’ string[8] = ‘h’ string[9] = ‘a’ string[10] = ‘t’ string[11] = ‘\0’
MΑΘ 106/3122 Ξ. Ζαμπούλης 12 Ανάγνωση Διάβασμα strings – Χρήση scanf scanf("%s", word); Αντιγράφει στο word[] Δεν χρειάζεται & (επειδή είναι και δείκτης) – Αφήνουμε χώρο στον πίνακα και για το '\0'
MΑΘ 106/3122 Ξ. Ζαμπούλης 1 2 3#include 4 5int main() 6{6{ 7 char string1[ 20 ], string2[] = "string literal"; 8 int i; 9 10 printf(" Enter a string: "); 11 scanf( "%s", string1 ); 12 printf( "string1 is: |%s|\nstring2: is |%s|\n“, string1, string2 ); 13 printf("string1 with spaces between characters is:\n“); for ( i = 0; string1[ i ] != '\0'; i++ ) 17 printf( "%c ", string1[ i ] ); printf( "\n" ); 20 return 0; 21} Enter a string: Hello there string1 is: Hello string2 is: string literal string1 with spaces between characters is: H e l l o
MΑΘ 106/3122 Ξ. Ζαμπούλης 14 Χρήσιμες Συναρτήσεις (string.h) size_t strlen( const char *s ); – Επιστρέφει τον αριθμό των χαρακτήρων πριν το ‘\0’ που βρίσκονται στο s (το μήκος string) char *strdup(const char *s1); – Δεσμεύει όση μνήμη χρειάζεται και αντιγράφει σε αυτήν το αλφαριθμητικό στο s1. Επιστρέφει την καινούργια μνήμη με το καινούργιο αντίγραφο του s1. Η δεσμευμένη μνήμη χρειάζεται να αποδεσμευτεί στο τέλος με την free.
MΑΘ 106/3122 Ξ. Ζαμπούλης 15 strlen /* strlen: return length of string s */ int strlen(char *s) { int n; for (n = 0; s[n] != '\0', n++) ; return n; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 16 strlen /* strlen: return length of string s */ int strlen(char *s) { char *p = s; while (*p != '\0') p++; return p − s; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 17 strlen /* strlen: return length of string s */ int strlen(char *s) { int n; for (n = 0; *s != '\0', s++) n++; return n; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 18 strcpy /* strcpy: copy t to s; array subscript version */ void strcpy(char *s, char *t) { int i; i = 0; while ((s[i] = t[i]) != '\0') i++; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 19 strcpy /* strcpy: copy t to s; pointer version */ void strcpy(char *s, char *t) { while ((*s = *t) != '\0') { s++; t++; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 20 Συναρτήσεις σύγκρισης (string.h) Σύγκριση αλφαριθμητικών – Συγκρίνονται οι ASCII κώδικες των χαρακτήρων int strcmp( const char *s1, const char *s2 ); – Συγκρίνει το s1 με το s2 – Επιστρέφει: αρνητικό αριθμό αν s1 < s2, μηδέν αν s1 == s2, ή θετικό αν s1 > s2
MΑΘ 106/3122 Ξ. Ζαμπούλης 21 Συναρτήσεις σύγκρισης (string.h) Σύγκριση αλφαριθμητικών – Συγκρίνονται οι ASCII κώδικες των χαρακτήρων int strcmp( const char *s1, const char *s2 ); – Συγκρίνει το s1 με το s2 – Επιστρέφει: αρνητικό αριθμό αν s1 < s2, μηδέν αν s1 == s2, ή θετικό αν s1 > s2 Αλφαριθμητική σειρά, με βάση το ASCII. Κάθε ψηφίο/χαραρακτήρας του string είναι ένα ψηφίο του αριθμού/αλφαρηθμητικού στο 256-δικό σύστημα.
MΑΘ 106/3122 Ξ. Ζαμπούλης 22 strcmp /* strcmp: return 0 if s>t */ int strcmp(char *s, char *t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == '\0') return 0; return s[i] − t[i]; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 23 strcmp /* strcmp: return 0 if s>t */ int strcmp(char *s, char *t) { for ( ; *s == *t; s++, t++) if (*s == '\0') return 0; return *s − *t; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 24 Παραδείγματα Πρόβλημα : Εκτυπώστε ανάστροφα το κείμενο που θα διαβαστεί από την οθόνη. #include #define N 100 void inversion(char *s) { int i; for (i = strlen(s)-1; i >= 0; --i) printf("%c",s[i]); printf(“\n”); } int main() { char s[N]; printf("Dwste mia le3h mexri %d xarakthres\n",N); scanf("%s",s); inversion(s); return 0; }
MΑΘ 106/3122 Ξ. Ζαμπούλης 25 Διαχείριση Αλφαριθμητικών Βρίσκονται στο Μετατρέπουν αλφαριθμητικά (αν είναι κατάλληλα) σε αριθμητικές τιμές
MΑΘ 106/3122 Ξ. Ζαμπούλης 26 Συναρτήσεις Ανάγνωσης και Εκτύπωσης Βρίσκονται στο int sprintf(char *s, const char *format, …)Ισοδύναμη με την printf μόνο που η έξοδος είναι στο string s και όχι στην οθόνη int sscanf(char *s, const char *format, …)Ισοδύναμη με την scanf μόνο που η είσοδος είναι από το string s και όχι από το πληκτρολόγιο char s[100]; char f[] = " "; float t1,t2,t3; sprintf(s,"%s",f); sscanf(s,"%f %f %f",&t1,&t2,&t3); printf("s = %s\nt1 = %f t2 = %f t3 = %f\n",s,t1,t2,t3);
MΑΘ 106/3122 Ξ. Ζαμπούλης 27 char myName [ 21 ] = “Huang” ; char yourName [ 21 ] ; if ( myName == yourName ) // compares addresses only! { // That is, 4000 and 6000 here.. // DOES NOT COMPARE CONTENTS!. } myName [0] ‘H’ ‘u’ ‘a’ ‘n’ ‘g’ ‘\0’... yourName [0] ‘H’ ‘e’ ‘a’ ‘d’ ‘i‘ ‘n’ ‘ g’ ‘t’ ‘o’ ‘n’ ‘\0’
MΑΘ 106/3122 Ξ. Ζαμπούλης 28 char myName [ 21 ] = “Huang” ; char yourName [ 21 ] ; strcpy ( yourName, myName ) ; // changes string yourName // OVERWRITES CONTENTS! myName [0] ‘H’ ‘u’ ‘a’ ‘n’ ‘g’ ‘\0’... yourName [0] ‘H’ ‘e’ ‘a’ ‘d’ ‘i‘ ‘n’ ‘ g’ ‘t’ ‘o’ ‘n’ ‘\0’ ‘u’ ‘n’ ‘g’ ‘\0’
MΑΘ 106/3122 Ξ. Ζαμπούλης 29 String literals Evaluating ″ dog ″ results in memory allocated for three characters ′ d ′, ′ o ′, ′ g ′, plus terminating NUL char *m = ″ dog ″ ; Note: If m is an array name, subtle difference: char m[10] = ″ dog ″ ; 10 bytes are allocated for this array This is not a string literal; It’s an array initializer in disguise! Equivalent to { ′ d ′, ′ o ′, ′ g ′, ′ \0 ′ }
MΑΘ 106/3122 Ξ. Ζαμπούλης 30 strlen() and size_t size_t strlen(char const *string); /* returns length of string */ size_t is an unsigned integer type, used to define sizes of strings and (other) memory blocks – Reasonable to think of “size” as unsigned”... – But beware! Expressions involving strlen() may be unsigned (perhaps unexpectedly) if (strlen(x) – strlen(y) >= 0)... avoid by casting: ((int) (strlen(x) – strlen(y)) >= 0) – Problem: what if x or y is a very large string? a better alternative: (strlen(x) >= strlen(y)) always true!
MΑΘ 106/3122 Ξ. Ζαμπούλης 31 strcmp() “string comparison” int strcmp(char const *s1, char const *s2); – returns a value less than zero if s1 precedes s2 in lexicographical order; – returns zero if s1 and s2 are equal; – returns a value greater than zero if s1 follows s2. Source of a common mistake: – seems reasonable to assume that strcmp returns “true” (nonzero) if s1 and s2 are equal; “false” (zero) otherwise – In fact, exactly the opposite is the case!
MΑΘ 106/3122 Ξ. Ζαμπούλης 32 main( ) { char name1[12],name2[12],mixed[25]; char title[20]; strcpy(name1,"Rosalinda"); strcpy(name2,"Zeke"); strcpy(title,"This is the title."); printf(" %s\n\n"title); printf("Name 1 is %s\n",name1); printf(Name 2 is %s\n",name2); if (strcmp(name1,name2)>0) /* return 1 if name1 > name2 */ strcpy(mixed,name1); else strcpy(mixed,name2); printf("The biggest name alphabetically is %s\n",mixed); strcpy(mixed,name1); strcat(mixed," "); strcat(mixed,name2); printf("Both names are %s\n",mixed); }
MΑΘ 106/3122 Ξ. Ζαμπούλης 33 Array of strings