Strings
E N D
Presentation Transcript
Strings Chapter 13
13.1 String Literal (字串) • A string literal is a sequence of characters enclosed within double quotes: "When you come to a fork in the road, take it." • String literals may contain escape sequences. • For example "Candy\nIs dandy\nBut liquor\nIs quicker.\n --Ogden Nash\n" Candy Is dandy But liquor Is quicker. --Ogden Nash
Continuing a String Literal • The backslash character (\) can be used to continue a string literal from one line to the next: printf("When you come to a fork in the \ road, take it. --Yogi Berra"); • When two or more string literals are adjacent, the compiler will join them into a single string: printf("When you come to a fork in the " "road, take it. --Yogi Berra");
To Store a String Literal • C treats string literals as character arrays. • The array contains a series of characters with '\0' (null character) at the end. • "It is 3.6%." Null character Space symbol
To Store a String Literal • String literals can be empty. ("") Null character
I/O with String Literals • Both printf and scanf expect a value of type char* as their first argument. • The following call of printf passes the address of "abc" (a pointer to where the letter a is stored in memory): printf("abc");
p Operations on String Literals • We can use a string literal wherever C allows a char * pointer: char *p; p = "abc"; • This assignment makes p point to the first character of the string.
Operations on String Literals • String literals can be subscripted: char ch; ch = "abc"[1]; The new value of ch will be the letter b. • A function that converts a number between 0 and 15 into the equivalent hex digit: char digit_to_hex_char(int digit) { return"0123456789ABCDEF"[digit]; }
Operations on String Literals • Attempting to modify a string literal causes undefined behavior: char *p = "abc"; *p = 'd';/*** WRONG ***/ • A program that tries to change a string literal may crash or behave erratically.
String Literals vs.Character Constants • A string literal containing a single character isn’t the same as a character constant. • "a" is represented by a pointer. • 'a' is represented by a character. • A legal call of printf: printf("\n"); • An illegal call: printf('\n'); /*** WRONG ***/
13.2 String Variables • Any one-dimensional array of characters can be used to store a string. • Storing "Tom Hanks"in char k[12] • Therefore, please define an array which size is larger than the string stored in it by at least 1 byte! (for the null character '\0' ) k End of a string Unassigned chars
String Variables • Difficulties with this approach: • It can be hard to tell whether an array of characters is being used as a string. • String-handling functions must be careful to deal properly with the null character. • Finding the length of a string requires searching for the null character.
Initializing a String Variable • A string variable can be initialized at the same time it’s declared: • char k[12] = "Tom Hanks"; • C compiler will fill all the elements not storing the string with null characters '\0' • Compiling error if no enough spaceto store the string End of a string k '\0' hereafter
Character Arrays vs. Character Pointers char date[] = "June 14"; char *datep = "June 14"; date[0] = 'j'; *datep = 'j'; date++; datep++; datep = &date[3]; *datep = 'E'; date datep datep datep
13.3 Reading and Writing Strings • printf • puts • scanf • gets • getch • getche
getch() and getche() • Functions to read a character from keyboard • They are in conio.h • getche(): the typed character will be shown on the screen • getch(): the typed character will not be shown on the screen
Example of Characters #include<stdio.h> #include<conio.h> void main() { char ch='B'; // assign a value of char ch = getche(); // recommended method printf("你輸入的是:%c\n", ch); scanf("%c", &ch); // not so recommended } A你輸入的是:A _
Writing Strings Using printf • The %s conversion specification allows printf to write a string: char str[] = "Are we having fun yet?"; printf("%s\n", str); • printf writes the characters in a string one by one until it encounters a null character. Are we having fun yet?
Writing Strings Using printf char color[12] = "blue"; char *p; p = color + 2; printf("%s\n%s\n", color, p); p char[ ] or char * color blue ue
Writing Strings Using printf • The specification %m.ps in printf • p is the number of characters to be displayed. • mis the size of a field to display a string in. • If a string has fewer than m characters, it will be right-justified within the field.
Writing Strings Using printf char *mName[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; for (k = 0; k < 12; k += 2)printf("[%.6s][%.6s]\n",mName[k],mName[k+1]); [Januar][Februa] [March][April] [May][June] [July][August] [Septem][Octobe] [Novemb][Decemb]
Writing Strings Using printf [January][February] [ March][ April] [ May][ June] [ July][August] [September][October] [November][December] char *mName[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; for (k = 0; k < 12; k += 2)printf("[%6s][%6s]\n",mName[k],mName[k+1]);
Writing Strings Using printf [Januar][Februa] [ March][ April] [ May][ June] [ July][August] [Septem][Octobe] [Novemb][Decemb] char *mName[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; for (k = 0; k < 12; k += 2)printf("[%6.6s][%6.6s]\n",mName[k],mName[k+1]);
Writing Strings Using printf [Januar][Februa] [March ][ April] [May ][ June] [July ][August] [Septem][Octobe] [Novemb][Decemb] char *mName[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; for (k = 0; k < 12; k += 2) printf("[%-6.6s][%6.6s]\n",mName[k],mName[k+1]);
Writing Strings Using puts • The C library also provides puts to write strings : puts(str); • After writing a string, puts always writes an additional new-line character.
Reading Strings Using scanf • The %s conversion specification allows scanf to read a string into a character array: scanf("%s", str); • str is treated as a pointer, so there’s no need to put the & operator in front of str.
Reading Strings Using scanf • When scanf is called, it skips white space, then reads characters and stores them in str until it encounters a white-space character (space, TAB, newline, etc.) • scanf always stores a null character at the end of the string.
Reading Strings Using scanf Ex. char name[12]; scanf("%s", name); %s Pointer to the storing location name \0 M a r y Mary Hanks (← input by the user)
Reading Strings Using gets • gets reads an entire line of input. gets(str); • Reads until it finds a new-line character. • Discards the new-line character instead of storing it; the null character takes its place. str H a n k s \0 M a r y Mary Hanks (← input by the user)
Reading Strings • In order to avoid reading more characters than one array can save, use fgets() instead of gets().
Reading Strings Using fgets 12 str H a n k s \n M a r y \0 Mary Hanks (← input by the user) • fgets reads an entire line from input until n - 1 characters are read. fgets(str, n, stdin); • Reserve the new-line character • Append the null character at the end
Reading Strings Using fgets str l y n H a n M a r i \0 Marilyn Hanks (← input by the user) • fgets reads an entire line from input until n - 1 characters are read. fgets(str, sizeof(str), stdin); • Reserve the new-line character • Append the null character at the end
13.4 Accessing the Charactersin a String Example: a function that counts the number of spaces in a string: int count_spaces(constchar s[]) { int count = 0, i; for (i = 0; s[i] != '\0'; i++) if (s[i] == ' ') count++; return count; }
13.5 Using C String Library • Included in <string.h> • strcpy – to copy strings • strlen – to get the length of a string • strcat – to concatenate two strings • strcmp – to compare two strings • …
Using the C String Library • Direct attempts to copy strings (using =) or compare strings (using ==) will fail. char str1[10], str2[10]; str1 = "abc";// Wrong: assigning to a constant (array name) str2 = str1;// Wrong: copying pointers, not strings if (str2 == str1)...;// Wrong: checking pointers POINT to the same// location, not checking content of strings
strcpy and strncpy char k1[12], k2[12]="12345678"; • strcpy(char *s1, char *s2):將 s2 內容copy給 s1 • strcpy(k1,"abcdefg");// k1: "abcdefg" • strcpy(k1, k2);// k1: "12345678" • strncpy(char *s1, char *s2, int n):將 s2 中最多 n 個字元 copy 到 s1 • strncpy(k1, k2, 4);// k1: "1234efg"
strcpy and strncpy char k1[12], k2[12]="12345678"; • 注意 strncpy() 並不會主動填上 '\0',請自行處理。 • strcpy(k1,"abcdefg");// k1: "abcdefg" • strncpy(k1, k2, 8);//k1: "12345678@#..." • k1[8] = '\0';//k1: "12345678" k1 1 2 3 4 5 6 7 8 \0
strlen • To get the length of a string(i.e. number of characters before '\0') Ex: char mystr[18]="Say hello!"; printf("字串長度 %d 個字元\n",strlen(mystr)); 字串長度 10 個字元
strlen • Note that "length of a string" is different from "size of an array for the string". Ex: char mystr[18]="Say hello!"; • String length: 10 • Array size: 18
strcmp • To compare two strings • strcmp(const char *s1, const char *s2): return 0 if s1 is equal to s2 1 s1 is larger than s2 -1 s1 is smaller than s2 Example: strcmp() return value • strcmp("aaa", "abb") • strcmp("aaa", "aaa") • strcmp("aaa", "aaaa") • strcmp("small", "big") -1 0 -1 1
Example of strcmp() void main(){ char name[20]; printf("請輸入姓名:"); scanf("%s", name); if (!strcmp(name, "林川傑")){ //表示相等 printf("哦!老師你來亂的喔!\n"); printf("不讓你登入!嘿嘿!\n"); } } //比較相等時也可寫 if (strcmp(name, "林川傑")==0)
Array of Strings char color[3][8]={"blue","yellow","red"}; char * * const color a constant pointer to pointer to characters color[0] color[1] color[2]
Array of Strings char name[3][20]; for (int i=0;i<3;i++){ printf("請輸入第%d位的姓名:",i+1); scanf("%s",name[i]); } Same type as char *, Which means &name[i][0] name[0] name[1] name[2]
Array of Strings • char * color[]={"red","green","blue"}; • Note that these strings are not necessarily stored in sequential memory. color[] char *
Arrays of Strings char planets[][8] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"}; Overhead:unused space for short strings
Arrays of Strings Overhead:space for pointers char *planets[] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"};
Practice • Write a function to check if a given string belongs to a specific set of strings. If so, return its index; otherwise return -1. • Example:indexOfStr(planet,8,"Mars") returns 3indexOfStr(planet,8,"May") returns -1indexOfStr(color,3,"Mars") returns -1
strcat and strncat char k1[20], k2[12]="12345678"; strcat(char *s1, char *s2):將 s2 內容 copy 到 s1 的結尾處 strcpy(k1,"abcdefg");// k1: "abcdefg" strcat(k1, k2);// k1:"abcdefg12345678" strncat(char *s1, char *s2, int n):將 s2 中最多 n 個字元 copy 到 s1的結尾處 strncat(k1, k2, 4);// k1: "abcdefg1234@#..."也不會填'\0'
中文 BIG5 碼 • 每個中文字是由兩個 bytes 所組成 • 中文的編碼有三區,每一區都照筆劃排列