Strings String Literals Continuing a String Literal Operations on String
Total Page:16
File Type:pdf, Size:1020Kb
3/4/14 String Literals • A string literal is a sequence of characters enclosed within double quotes: "When you come to a fork in the road, take it." Strings • String literals may contain escape sequences. • Character escapes often appear in printf and scanf format strings. Based on slides from K. N. King and Dianna Xu • For example, each \n character in the string "Candy\nIs dandy\nBut liquor\nIs quicker.\n --Ogden Nash\n" causes the cursor to advance to the next line: Bryn Mawr College Candy CS246 Programming Paradigm Is dandy But liquor Is quicker. --Ogden Nash Continuing a String Literal How String Literals Are Stored • The backslash character (\) • The string literal "abc" is stored as an array of printf("When you come to a fork in the road, take it. \ four characters: --Yogi Berra"); Null o In general, the \ character can be used to join two or character more lines of a program into a single line. • When two or more string literals are adjacent, the compiler will join them into a single string. • The string "" is stored as a single null character: printf("When you come to a fork in the road, take it. " "--Yogi Berra"); This rule allows us to split a string literal over two or more lines How String Literals Are Stored Operations on String Literals • Since a string literal is stored as an array, the • We can use a string literal wherever C allows a compiler treats it as a pointer of type char *. char * pointer: • Both printf and scanf expect a value of type char *p; char * as their first argument. p = "abc"; • The following call of printf passes the address • This assignment makes p point to the first of "abc" (a pointer to where the letter a is stored character of the string. in memory): printf("abc"); 1 3/4/14 Operations on String Literals Operations on String Literals • String literals can be subscripted: • Attempting to modify a string literal causes char ch; undefined behavior: ch = "abc"[1]; //ch is ‘b’ char *p = "abc"; • A function that converts a number between 0 and *p = 'd'; /*** WRONG ***/ 15 into the equivalent hex digit: • A program that tries to change a string literal may char digit_to_hex_char(int digit) crash or behave erratically. { return "0123456789ABCDEF"[digit]; } String Literals vs Character Constants String Variables • A string literal containing a single character is not • Any one-dimensional array of characters can be the same as a character constant. used to store a string. o "a" - represented by a pointer. • A string must be terminated by a null character. o 'a’ - represented by an integer. #define STR_LEN 80 • A legal call of printf: … char str[STR_LEN+1]; printf("\n"); o Defining a macro that represents 80 and then adding • An illegal call: 1 separately is a common practice. printf('\n'); /*** WRONG ***/ Character Arrays vs Initializing a String Variable Character Pointers • A string variable can be initialized at the same time • The declaration it’s declared: Not a string literal. char date[] = "June 14"; An abbreviation for char date1[8] = "June 14"; Array name Characters can be modified an array initializer char date4[] = "June 14"; declares date to be an array, • The similar-looking char *date = "June 14"; Pointer variable String literal – should not be modified. char date2[9] = "June 14"; declares date to be a pointer. • Thanks to the close relationship between arrays and pointers, either version can be used as a string. 2 3/4/14 Character Arrays vs Character Pointers Reading and Writing Strings • char *p; //does not allocate space for a string. • Writing a string • Using an uninitialized pointer variable as a string is a o printf serious error. o puts An attempt at building the string "abc": • Reading a string char *p; o in a single step p[0] = 'a'; /*** WRONG ***/ p[1] = 'b'; /*** WRONG ***/ • scanf p[2] = 'c'; /*** WRONG ***/ • gets p[3] = '\0'; /*** WRONG ***/ o read strings one character at a time. • Before we can use p as a string, it must point to an • Reading a string is a bit harder, because the input may array of characters. be longer than the string variable into which it’s being char str[STR_LEN+1], *p; stored. p = str; printf and puts printf and puts • The %s conversion specification allows printf • A conversion specification: %m.ps to write a string: o the first p characters of a string to be displayed in a field of size m. char str[] = "Are we having fun yet?"; • To print part of a string, use the conversion printf("%s\n", str); specification %.ps. The output will be • printf("%.6s\n", str); //Are we Are we having fun yet? • The %ms conversion will display a string in a field of size m. • printf writes the characters in a string one by o If the string has fewer than m characters, it will be right- one until it encounters a null character. justified within the field. o To force left justification instead, we can put a minus sign in front of m. printf and Strings Displaying Substrings int main() { int main() { char s[] = "01234"; • %d, %c, %f: char s[] = "01234"; char *p; Displays the given char *p; p = s; p = s; value printf("%c\n", s[0]); printf("%s\n", s); • %s: Displays printf("%s\n", p); printf("%c\n", *s); characters from printf("%c\n", *(p+1)); printf("%s\n", s + 0); the specified printf("%s\n", &(s[0])); printf("%s\n", s); address until printf("%s\n", p+1); printf("%s\n", s + 2); } '\0' printf("%s\n", &(s[2])); } 3 3/4/14 Displaying Characters of a String printf and puts puts(str); int main() { • After writing a string, puts always writes an char s[] = "01234"; char *p; additional new-line character. p = s; #define BUFLEN 200 printf("%c\n", s[0]); printf("%c\n", *p); int main() { printf("%c\n", *(p + 0)); char buf[BUFLEN]; printf("%c\n", s[2]); gets(buf); puts adds '\n' to output, printf("%c\n", *(p + 2)); puts(buf); equivalent to } return 0; printf("%s\n", buf); } scanf and gets scanf and gets • The %s conversion specification allows scanf to • gets: read an entire line of input read a string into a character array: • Properties of gets: scanf("%s", str); str is treated as a pointer o Does not skip white space before starting to read • When scanf is called, no & in front of str input. o it skips white space, o Reads until it finds a new-line character. o reads characters and stores them in str until it o Discards the new-line character instead of storing it; encounters a white-space character. the null character takes its place. • scanf always stores a null character at the end of the string. scanf and gets scanf and gets • Consider the following program fragment: • As they read characters into an array, scanf and char sentence[SENT_LEN+1]; have no way to detect when it’s full. gets printf("Enter a sentence:\n"); • Consequently, they may store characters past the scanf("%s", sentence); end of the array, causing undefined behavior. • Suppose that the user enters the line To C, or not to C: that is the question. • scanf:use the conversion specification %ns • scanf will store the string "To" in sentence. instead of %s. • gets will store the string • gets is inherently unsafe; fgets is a much better " To C, or not to C: that is the alternative. question." in sentence. 4 3/4/14 Accessing the Characters Accessing the Characters in a String in a String • A function that counts the number of spaces in a • A version that uses pointer arithmetic instead of string: array subscripting : int count_spaces(const char s[]) int count_spaces(const char *s) { { int count = 0, i; int count = 0; for (i = 0; s[i] != '\0'; i++) for (; *s != '\0'; s++) if (s[i] == ' ') if (*s == ' ') count++; count++; return count; return count; } } 5 .