C programming---String String Literals A string literal is a sequence of characters enclosed within double quotes: “hello world” Escape Sequence in String Literals “Candy\n Is dandy\n But liquor\n Is quicker.\n Candy Is dandy But liquor Is quicker. “\1234” contains two characters: ‘\123’ and ‘4’ “\189” contains three characters: ‘\1’ , ‘8’ and ‘9’ “\x0” …. “\xff”: hex escape Continuing a String Literal printf(“When you come to a fork in the road, \ take it --- Yogi Berra”); Wrecking the program’s indented structure printf( “When you come to a fork in the road, ” “take it --- Yogi Berra”); How String Literals Are Stored •When we call printf and supply a string literal as an argument, what are we actually passing? •C treats string literals as character arrays. •A string literal of length n will be stored in a n + 1 bytes memory. •The last character in the array is the null character as a marker for the end of the string How String Literals Are Stored null character: ‘\0’ Do not confuse it with ‘0’ Since a string literal is stored as an array, the compiler treats it as a pointer of type char *. So when printf(“abc”) is called, the address of “abc” is passed. Operations on String Literal char *p = “abc”; char ch = “abc”[1]; char digit_to_hex_char(int digit) { “0123456789ABCDEF”[digit]; } Operations on String Literal char *p = “abcd”; *p = ‘o’; “a” is different from ‘a’ “a” is represented by a pointer to a memory address ‘a’ is represented by an integer printf(“a”); printf(‘a’); String Variables Java has a String type, but C does not. Any one-dimensional array of characters can be used to store a string. There is no faster way to determine the length of a string than a character-bycharacter search for ‘\0’ String Variable #define STR_LEN 90 …….. char str[STR_LEN + 1]; char data4[] = “June 14” char data1[8] = “June 14”; J u n e 1 4 \0 \0 \0 char data2[9] = “June 14”; J u n e 1 4 e 1 4 char data3[7] = “June 14”; J u n Character Arrays V.S. Character Pointers char data[] = “june 14”; char *data = “june 14”; Character Arrays V.S. Character Pointers char str[STR_LEN + 1], *p; p = str; In this way you can manipulate “string” with pointers p[0] = ‘o’; p[1] = ‘r’; But char *p; p[0] = ‘a’; p[1] = ‘b’; p[2] = ‘c’; THIS IS WRONG BECAUSE:? Reading and Writing Strings • Writing strings with printf and puts printf(“%s”, str); puts(str); • Reading strings with scanf and gets scanf(“%s”, str); //skip white space gets(str); //doesn’t skip white space before starting to read the string //reads until it finds a new-line character Reading Strings Character by Character int read_line(char str[], int n) { int ch, i = 0; while((ch = getchar()) != ‘\n’) { if(i < n) str[i++] = ch; } str[i] = ‘\0’; return i; } Accessing the Characters in a String int count_spaces(const char s[]) { int count = 0, i; for(i=0; s[i]!=‘\0’; i++) if(s[i] == ‘ ‘) count++; return count; } int count_spaces(const char s*) { int count = 0; for(; *s!=‘\0’; s++) if(*s == ‘ ‘) count++; return count; } Using the C String Library char str[10], str2[10]; str1 = “abc”; // WRONG str2 = str1; // WRONG if(str1 == str2) // WRONG <string.h> The strcpy(String Copy) Function char *strcpy(char *s1, const char *s2); str2 = “abcd”; strcpy(str2, “abcd”); strcpy(str1, str2); strcpy(str1, strcpy(str2, “abcd”)); It is safer to call strncpy, but it is slower. char *strncpy(char *s1, const char *s2, size_t s); The strlen(String Length) Function size_t strlen(const char *s); int len = strlen(“abc”); The strcat (String Concatenation) Function char *strcat(char *s1, const char *s2); strcpy(str1, “abc”); strcat(str1, “def”); char str1[6] = “abc”; strcat(str1, “def”); /*wrong*/ strncat(s1, s2, strlen(s1)-strlen(s2)-1); The strcmp(String Comparison) Function int strcmp(const char *s1, const char *2); if(strcmp(s1, s2) < 0) if(strcmp(s1, s2) <= 0) strcmp compares strings based on their lexicographic ordering, which resembles the way words are arranged in a dictionary: (1)The first i characters of s1 and s2 match, but the (i+1)st character of s1 is less than the (i+1)st character of s2. “abc” < “bcd” “abd” < “abe” (2)All characters of s1 match s2, but s1 is shorter than s2. “abc” < “abcd” The strcmp(String Comparison) Function (1) The characters in each of the sequences ‘A’-’Z’, ‘a’’z’, and ‘0’-’9’ have consecutive codes. (2) All upper-case letters are less than all lower-case letters: ‘A’-’Z’(65-90) ‘a’-’z’(97-122) (3) Digits are less than letters: ‘0’-’9’(48-57) (4) Spaces are less than all printing characters: 32 in ASCII String Idioms Searching for the End of a String size_t strlen(const char *s) { size_t n; for(n=0; *s!=‘\0’; s++) n++; return n; } size_t strlen(const char *s) { size_t n = 0; for(; *s; s++) n++; return n; } size_t strlen(const char *s) { size_t n = 0; for(; *s!=‘\0’; s++) n++; return n; } size_t strlen(const char *s) { size_t n = 0; for(; *s++; ) n++; return n; } String Idiom Searching for the End of a String size_t strlen(const char *s) { size_t n = 0; while(*s++) n++; return n; } size_t strlen(const char *s) { const char *p = s; while(*s) s++; return s - p; } String Idiom while(*s) s++; while(*s++) ; String Idiom Copying a String char * strcat(char *s1, const char *s2) { char *p = s1; while(*p) p++; while(*p++ = *s++) // idiom ; return s1; } Array of Strings char planets[][8] = { “Mercury”, “Venus”, “Earth”, “Mars”, “Jupiter”, “Saturn”, “Uranus”, “Neptune”, “Pluto”}; char *planets[] = { “Mercury”, “Venus”, “Earth”, “Mars”, “Jupiter”, “Saturn”, “Uranus”, “Neptune”, “Pluto”}; Array of Strings Mercury\0 Venus\0 Earth\0 Mars\0 Jupiter\0 Command-Line Arguments argv Program name -l\0 remind.c\0 int main(int argc, char *argv[]) { ………. }