Problem Solving and Program Design in C Chap
Problem Solving and Program Design in C Chap. 8 Strings Chow-Sing Lin
CSIE@NUTN String Basics • String - a data structure which is a grouping of characters • Calls to scanf or printf used a string constant as the first argument. printf("Average = %. 2 f", avg); • A string of 14 characters. • The blank in the string are characters just as valid as those requiring ink! Dr. Chow-Sing Lin Strings - CH 9 2
CSIE@NUTN Declaring and Initializing String Variables • A string in C is implemented as an array, so declaring a string variable is the same as declaring an array of type char. In char str[20] = "Initial value" ; • str in memory after this declaration with initialization – ‘ ’ null character that marks the end of a string. [0] I [4] n i Dr. Chow-Sing Lin t i [14] [9] a l v a l Strings - CH 9 u e ? ? [19] ? ? 3
CSIE@NUTN Arrays of Strings • An array of strings is a two-dimensional array of characters in which each row is one string – The following are statements to declare an array to store up to 30 names. Each of which is less than 25 characters long. #define NUM_PEOPLE 30 #define NAME_LEN 25 char names[NUM_PEOPLE][NAME_LEN]; Dr. Chow-Sing Lin Strings - CH 9 4
CSIE@NUTN Arrays of Strings (cont. ) • Initialize an array of strings at declaration in the following manner char month[12][10] = {“January”, ”February”, ”March”, ”April”, ”May” , ”June”, ”July”, ”August”, ”September”, ”October”, ”November”, ”December”} ; Dr. Chow-Sing Lin Strings - CH 9 5
CSIE@NUTN Input / Output with printf and scanf • printf and scanf can handle string arguments as long as the placeholder %s is used in the format string printf(“Topic: %sn”, string_var); – %s placeholder in a printf format string can be used with a minimum field with as shown printf(“***%8 s***%3 s***n”, ”Short” , ”Strings”); – Left-justified printf(“%-20 sn”, president); Dr. Chow-Sing Lin Strings - CH 9 6
CSIE@NUTN Figure 9. 1 Right and Left Justification of Strings Dr. Chow-Sing Lin Strings - CH 9 7
CSIE@NUTN Input / Output with printf and scanf Dr. Chow-Sing Lin Strings - CH 9 8
CSIE@NUTN Execution of scanf(“%s”, dept); • scanf () skips leading whitespace characters such as blanks, newline, and tabs. Dr. Chow-Sing Lin Strings - CH 9 9
CSIE@NUTN Invalid input format • Function scanf would have difficulty, if – some essential whitespace between values were omitted – a non-whitespace separator were substituted • For example • If the data were entered as • > MATH 1270 TR 1800 – scanf would store the eight-character string “MATH 1270” Dr. Chow-Sing Lin Strings - CH 9 10
CSIE@NUTN Invalid Input Format (cont. ) • For example • > MATH, 1270, TR, 1800 • scanf function would store the entire 17 -character string plus ‘ ’ – Example 8. 1 Dr. Chow-Sing Lin Strings - CH 9 11
CSIE@NUTN String Library Functions : Assignment and Substrings • Accustomed to using the assignment operator = to copy data into a variable – Not working for string assignment! • The array address is constant and cannot be changed through assignment char one_str[20]; one_str =“test string” ; /* does not work*/ • Some String Library Functions from string. h – Page 481 -- Table 8. 1 – Appendix B-13 Dr. Chow-Sing Lin Strings - CH 9 12
CSIE@NUTN String Assignment • Function strcpy copies the string that is its second argument into its first argument strcpy(one_str, “test string”) ; /* ok */ strcpy(one_str, ”a very long test string”); – Overflow one_str, storing the final characters ‘i’, ‘n’, ‘g’, and ‘ ’ in memory allocated for other variables. Dr. Chow-Sing Lin Strings - CH 9 13
CSIE@NUTN String Assignment (cont. ) • The string library provides another stringcopying function named strncpy – An argument specifying the number of characters to copy(call this number n) strncpy(one_str, “Test String”, 20); • The same as the call strcpy(one_str, ”Test String”); [0] T [4] e s Dr. Chow-Sing Lin t [9] S t r i n [14] g Strings - CH 9 [19] O O O 14
CSIE@NUTN String Assignment (cont. ) • The string library provides another string-copying function named strncpy(one_str, ”A very long test string”, 20); [0] A [4] v e r [9] y l o n [14] g t e s [19] t s t r – This is not a valid string in one_str array!! – One can assign as much as will fit of a source string(source) to a destination(dest) of length dest_len by using these two statements strncpy(dest, source, dest_len -1) ; dest[dest_len-1]=‘ ’ ; Dr. Chow-Sing Lin Strings - CH 9 15
CSIE@NUTN Substrings • The data areas of strncpy and the calling function just before the return from the call to strncpy in this code fragment char result[10], s 1[15]=“Jan. 30, 1996”; strncpy(result, s 1, 9); result[9]=‘ ’; Dr. Chow-Sing Lin Strings - CH 9 16
CSIE@NUTN Substrings(cont’) • The array reference with no subscript actually represents the address of the initial array element. • The code fragment would extract the substring “ 30” char result[10], s 1[15]=“Jan. 30, 1996”; strncpy(result, &s 1[5], 2); result[2]=‘ ’; Dr. Chow-Sing Lin Strings - CH 9 17
CSIE@NUTN Examples • Example 8. 2 (page 484) • Example 8. 3 (how? Interesting …) Dr. Chow-Sing Lin Strings - CH 9 18
CSIE@NUTN Longer Strings : Concatenation • Concatenation – String library function strcat and strncat modify their first string argument by adding all or part of their second string argument at the end of the first argument. – Book Page 489 example 8. 4 Dr. Chow-Sing Lin Strings - CH 9 19
CSIE@NUTN Strlen #define STRSIZ 20 char s 1[STRSIZ] = “Jupiter “ , s 2[STRSIZ] = “Symphony” ; printf(“%d %dn”, strlen(s 1), strlen(strcat(s 1, s 2))) ; printf(“%sn”, s 1); • strlen(s 1) 8 • strlen(strcat(s 1, s 2)) 16 Dr. Chow-Sing Lin Strings - CH 9 20
CSIE@NUTN strlen (cont’) If (strlen(s 1) + strlen(s 2) < STRSIZ) strcat(s 1, s 2) ; else { strncat(s 1, s 2, STRSIZ – strlen(s 1) – 1) ; s 1[STRSIZ-1] = ‘ ’; } • The condition correctly verifies that the sum of the length of s 1 and s 2 is strictly less than STRSIZ. Dr. Chow-Sing Lin Strings - CH 9 21
CSIE@NUTN Distinction Between Characters and Strings • ‘Q’ and “Q” are different !! Q Character ‘Q’ Dr. Chow-Sing Lin Q ? ? ? … String “Q” (represented by its initial address) Strings - CH 9 22
CSIE@NUTN Scanning a Full Line • scanf() and fscanf() are not suitable for scanning a full line for treating blanks as delimiters. – Use gets() or fgets() char line[80]; printf(“Type in a line of data. n >”); gets(line); Dr. Chow-Sing Lin Strings - CH 9 23
CSIE@NUTN Scanning a Full Line(cont. ) • If the user responds to the prompt as follows by gets Type in a line of data. > Here is a short sentence. – The value stored in line[] would be Here is a short sentence. – The ‘n’ character representing the <return> or <enter> key pressed at the end of the sentence is not stored. – gets can overflow its string argument if the user enters a longer data line than will fit. Dr. Chow-Sing Lin Strings - CH 9 24
CSIE@NUTN Scanning a Full Line (cont. ) • Function fgets() will never store more than n-1 characters from the data file, and the final character stored will always be ‘ ’ – If fgets() has room to store the entire line of data, it will include ‘n’ before ‘ ’. – If the line is truncated, no ‘n’ is stored. • When a call to fgets encounters the end of file, the value returned is the address 0, which is considered the null pointer. Dr. Chow-Sing Lin Strings - CH 9 25
CSIE@NUTN Figure 8. 8 Demonstration of Whole. Line Input Dr. Chow-Sing Lin Strings - CH 9 26
CSIE@NUTN Figure 9. 8 Demonstration of Whole. Line Input Dr. Chow-Sing Lin Strings - CH 9 27
CSIE@NUTN Exercises for section 8. 3 • Give the string pres(value is “Adams, John Quincy”) and the 40 character temporary variables tmp 1 and tmp 2, what string is displayed by the following code fragment? strncpy(tmp 1, &pres[7], 4); tmp 1[4]=‘ '; strcat(tmp 1, " "); strncpy(tmp 2, pres, 5); tmp 2[5]=‘ '; printf("%sn", strcat(tmp 1, tmp 2)); Dr. Chow-Sing Lin Strings - CH 9 Answer John Adams 28
CSIE@NUTN String Comparison • If the first n characters of str 1 and str 2 match and str 1[n], str 2[n] are the first non-matching corresponding characters, str 1 is less than str 2 if str 1[n] < str 2[n] str 1 t h r i l l str 2 t h r o w First 3 letters match str 1[3] < str 2[3] ‘i‘ < ‘o’ str 1 < str 2 Dr. Chow-Sing Lin str 1 e n e r g y str 2 f o r c e First 0 letters match str 1[0] < str 2[0] ‘e‘ < ‘f’ str 1 < str 2 Strings - CH 9 29
CSIE@NUTN String Comparison(cont. ) • If str 1 is shorter than str 2 and all the characters of str 1 match the corresponding characters of str 2 , str 1 is less than str 2 str 1 j o y str 2 j o y o u s Dr. Chow-Sing Lin Strings - CH 9 30
CSIE@NUTN String Comparison(cont. ) • Possible Results of strcmp(str 1 , str 2) Relationship Value Returned Example str 1 is less then str 2 negative integer str 1 is “marigold” str 2 is “tulip” str 1 equals str 2 zero str 1 and str 2 are both “end” str 1 is greater than str 2 positive integer Dr. Chow-Sing Lin Strings - CH 9 str 1 is “shrimp” str 2 is “crab” 31
CSIE@NUTN Example 8. 5 • When alphabetizing a list, string comparisons are essential. – Use selection sort. – Compares the numeric and string versions of code that compares list elements in the search for the index of smallest. Dr. Chow-Sing Lin Strings - CH 9 32
CSIE@NUTN EXAMPLE 8. 6 • When we process a list of string data interactively, we often do not know in advance how much data will be entered. • Use a sentinel-controlled loop to prompt the user to type in the sentinel value when entry of the data is complete. Dr. Chow-Sing Lin Strings - CH 9 33
CSIE@NUTN Exercises for Section 8. 4 • Write a message indicating whether name 1 and name 2 match Answer if(strcmp(name 1 , name 2)==0) printf(“Names match. n”); else printf(“Names do not match. n”); Dr. Chow-Sing Lin Strings - CH 9 34
CSIE@NUTN Exercises for section 8. 4(cont. ) • Store in the string variable word the value either of w 1 or of w 2. • Choose the value that comes first alphabetically. Answer if (strcmp(w 1 , w 2)< 0) strcpy(word, w 1); else strcpy(word, w 2); Dr. Chow-Sing Lin Strings - CH 9 35
CSIE@NUTN Arrays of pointers • Let’s look closely at the code that exchanges two strings Dr. Chow-Sing Lin Strings - CH 9 36
CSIE@NUTN Arrays of pointers(cont. ) • Copy strings between memory cells. – BAD !! Dr. Chow-Sing Lin Strings - CH 9 37
CSIE@NUTN Arrays of pointers(cont. ) • C’s use of pointers to represent arrays presents us with an opportunity to develop an alternate approach to our sorting problem • char *alpha[5]; Dr. Chow-Sing Lin Strings - CH 9 38
CSIE@NUTN Example 8. 7 • The Open School admits children to its kindergarten in the order in which they apply • Most of the staff’s use of the list of applicants is made easier if the list is alphabetized • How the order of string exchanged in select_sort_str() ? ? – Only the pointers are exchanged!! (page. 499) Dr. Chow-Sing Lin Strings - CH 9 39
CSIE@NUTN Example 9. 7(cont. ) Dr. Chow-Sing Lin Strings - CH 9 40
CSIE@NUTN Example 9. 7(cont. ) Dr. Chow-Sing Lin Strings - CH 9 41
CSIE@NUTN Example 9. 7(cont. ) Only the pointers of strings are exchanged !! Dr. Chow-Sing Lin Strings - CH 9 42
CSIE@NUTN Arrays of string constants • Two alternative for representing the list of month char month[12][10] = {“January” , “February” , “March” , “April” , “May” , “June” , “July” , “August” , “September” , “October” , “November” , “December” }; char *month[12] = {“January” , “February” , “March” , “April” , “May” , “June” , “July” , “August” , “September” , “October” , “November” , “December” }; Dr. Chow-Sing Lin Strings - CH 9 43
CSIE@NUTN Character Operations • Character Input/output – getchar() • It is used to get the next character from the standard input source • getchar does not expect the calling module to pass as an argument the address of a variable in which to store the input character. Either of the following two expressions can be used to store the next available input character in ch. scanf(“%c” , &ch) ch = getchar() • getc(inp) -- get a char from a file. Dr. Chow-Sing Lin Strings - CH 9 44
CSIE@NUTN Example 8. 8 • Write a scanline function that use getchar Dr. Chow-Sing Lin Strings - CH 9 45
CSIE@NUTN Char output • The standard library’s single-character output facilitate are putchar (for display on the standard output device) and putc (for files). putchar(‘a’) ; putc(‘a’, outp); Dr. Chow-Sing Lin Strings - CH 9 46
CSIE@NUTN Character analysis and conversion • We need to know if a character belongs to a particular subset of the overall character set. • The library #include as <ctype. h> defines facilities for answering questions like these and also provides routines to do common character conversions like uppercase to lowercase or lowercase to uppercase. Dr. Chow-Sing Lin Strings - CH 9 47
CSIE@NUTN Character analysis and conversion(cont. ) Factility Checks Example isalpha if argument is a letter of the alphabet if(isalpha(ch)) printf(“%c is a letter n”, ch); isdigit if argument is one of the ten decimal dec_digit = isdigit(ch); digits islower (isupper) if argument is a lowercase (or uppercase) letter of the alphabet if (islower(fst_let)){ print(“n Error: sentence”); printf(“should begin with a”); printf(“capital letter. n”); } ispunct if argument is a punctuation character, that is , a noncontrol character that is not a spacem a letter of the alphabet, or a digit if(ispunct (ch)) printf(“Punctuation mark: %c n” , ch); isspace if argument is a whitespace c = gether(); character such as a space, a newline, While (isspace(c) && c != EOF) or a tab c = gether(); Dr. Chow-Sing Lin Strings - CH 9 48
CSIE@NUTN Character analysis and conversion(cont. ) Factility Checks Example tolower (toupper) its lowercase(or uppercase) letter argument to the uppercase(or lowercase) equivalent and returns this equivalent as the value of the call If (islower(ch)) printf(“Capital %c = %c n”, ch , toupper(ch)); Dr. Chow-Sing Lin Strings - CH 9 49
CSIE@NUTN Example 8. 9 • A function string_greater that could be used to find out-of-order elements when alphabetizing a list of strings in a situation in which the case of the letters should be ignored. Dr. Chow-Sing Lin Strings - CH 9 50
CSIE@NUTN Example 8. 9(cont. ) Dr. Chow-Sing Lin Strings - CH 9 51
String-to-Number and Number-to-String Conversions CSIE@NUTN • Review of user of scanf Data ( means blank) Declaration Statement char t scanf(“%c”, &t); int n scanf(“%d”, &n); double x scanf(“%lf”, &x); char str [10] scanf(“%s” str); Dr. Chow-Sing Lin g n A 32 -8. 6 +19 4. 32 -8 1. 76 e-3 hello n overlengthy Strings - CH 9 Value Stored 32 -8 19 4. 32 -8. 0. 00176 hello overlengthy (overruns length of 52 str)
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • Placeholders used with printf Value Placeholder Output ( means blank) ‘a’ %c %3 c %-3 C a %d %2 d %4 d %-5 d -10 -10 -10 Dr. Chow-Sing Lin a a Strings - CH 9 53
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • Placeholders used with printf (Cont. ) Value Placeholder Output ( means blank) 49. 76 %. 3 f %. 1 f %10. 2 f %10. 3 e 49. 760 49. 8 49. 76 4. 976 e+01 “fantastic” %s %6 s %12 s %-12 s %3. 3 s Dr. Chow-Sing Lin fantastic fan Strings - CH 9 54
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • The stdio library gives us this ability through similar function – sprintf() – sscanf() • The sprintf function requires space for a string as its first argument Dr. Chow-Sing Lin Strings - CH 9 55
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • Consider this call to sprintf – Assume that s has been declared as char s[100] – The value of type int variables mon, day, and year mon day year 8 23 1914 sprintf(s, “%d/%d/%d”, mon, day, year); Dr. Chow-Sing Lin Strings - CH 9 56
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • Function sprintf substitutes values for placeholders just as printf does • sprintf stores it in the character array accessed by its initial argument s 8 / 2 3 / 1 9 1 4 Dr. Chow-Sing Lin Strings - CH 9 57
CSIE@NUTN String-to-Number and Number-to-String Conversions (Cont. ) • example – the illustration that follows shows how stores values from the first string sscanf(“ 85 96. 2 hello”, “%d%1 f%s”, &num, &val, word); Dr. Chow-Sing Lin num val 85 96. 2 word h e l l o Strings - CH 9 58
CSIE@NUTN Example 8. 11 • The conversion of DATE to three numbers (12 January 1941 1 12 1941) and reverse conversion. Dr. Chow-Sing Lin Strings - CH 9 59
CSIE@NUTN Figure 8. 18 Functions That Convert Representations of Dates 1 -60
CSIE@NUTN Figure 8. 18 Functions That Convert Representations of Dates (cont’d) 1 -61
CSIE@NUTN Figure 8. 18 Functions That Convert Representations of Dates (cont’d) 1 -62
CSIE@NUTN Figure 8. 18 Functions That Convert Representations of Dates (cont’d) 1 -63
CSIE@NUTN String Processing Illustrated • Case Study – Text Editor – Problem • Design and implement a program to perform editing operations on a line of text • editor should be able to – locate a specified target substring – delete a substring – insert a substring at a specified location • editor should expect source strings of less than 80 characters Dr. Chow-Sing Lin Strings - CH 9 64
CSIE@NUTN Case Study (Cont. ) Dr. Chow-Sing Lin Strings - CH 9 65
CSIE@NUTN Case Study (Cont. ) Dr. Chow-Sing Lin Strings - CH 9 66
CSIE@NUTN Case Study (Cont. ) Dr. Chow-Sing Lin Strings - CH 9 67
CSIE@NUTN Dr. Chow-Sing Lin Strings - CH 9 68
CSIE@NUTN Dr. Chow-Sing Lin Strings - CH 9 69
CSIE@NUTN Dr. Chow-Sing Lin Strings - CH 9 70
CSIE@NUTN Dr. Chow-Sing Lin Strings - CH 9 71
CSIE@NUTN Figure 8. 21 Sample Run of Text Editor Program Dr. Chow-Sing Lin Strings - CH 9 72
CSIE@NUTN Common Programming Error • When we work with numeric values or single characters – we commonly compute a value of interest in a function – storing the result value temporarily in a local variable of the function – until it is returned to the calling module using the return statement – But such functions do not actually return a string value Dr. Chow-Sing Lin Strings - CH 9 73
CSIE@NUTN Common Programming Error (Cont. ) • The function’s data area is deallocated as soon as the return statement is executed – it is not valid to access from the calling module the string the function constructed in its own variable • Figure 8. 22 shows a poor rewrite of the scanline function from Fig. 8. 15 Dr. Chow-Sing Lin Strings - CH 9 74
CSIE@NUTN Figure 8. 15 Implementation of scanline Function Using getchar Dr. Chow-Sing Lin Strings - CH 9 75
CSIE@NUTN Figure 8. 22 Flawed scanline Returns Address of Deallocated Space Dr. Chow-Sing Lin Strings - CH 9 76
CSIE@NUTN Common Programming Error (Cont. ) • String use is the overflow of character arrays allocated for strings [0] [4] M A T H , [9] 1 2 7 0 , space not allocated for dept T R , 1 8 0 0 Execution of scanf(“%s%d”, dept, &course_num, days, &time); on Entry of Invalid Data • Whatever was stored in the cells following array dept has just been overwritten !! – If memory was being used for other program variables, values will appear to change spontaneously Dr. Chow-Sing Lin Strings - CH 9 77
- Slides: 77