EXERCISES ON CHARACTERS AND STRINGS READING ------- Sedgewick, 108-114 Kernighan and Ritchie, 1.5-6, 5.5 King, Chapter 13.1-13.5 (Strings) EXERCISES --------- 0. What does the following code fragment print out. #include int main(void) { char c1 = 'A', c2 = '8'; int m = 66, n; printf("'A' : %c %d\n", c1, c1); printf("'8' : %c %d\n", c2, c2); printf("70 : %c %d\n", m, m); printf("'A' + 2 : %c %d\n", c1 + 2, c1 + 2); n = (c2 - '0') * m; printf("n = %d\n", n); return 0; } 1. Which of the following sets i to the length of the string a? A. i = strlen(a); B. i = 0; while (a[i] != '\0') ++i; C. i = 0; while (a[i] != '\0') i++; D. for (i = 0, b = a; *b != '\0'; b++) i++; E. for (i = 0; a[i] != '\0'; i++) ; F. b = a; while (*b++) ; i = b-a-1; G. b = a; while (*b) b++; i = b-a; 2. What is wrong with the following program for printing out the length of a word from standard input? #include int main(void) { int n; char a[101]; scanf("%s", a); for (n = 0; *a != '\0'; a++) n++; printf("%d %s\n", n, a); return 0; } 3. Explain what the following program does. #include #include int main(void) { int i, N; char word[101]; while (scanf("%s", word) != EOF) { N = strlen(word); for (i = 0; i < N; i++) if (word[i] <= word[i+1]) break; if (i == N) printf("%d %s\n", N, word); } } return 0; } 4. Write a C function that takes a string as an argument, and prints the string in PigLatin. Recall, in PigLatin, you move the first letter of the word to the end, and then add "ay". E.g., "this was fun" -> "histay asway unfay". 5. Write a program that prints out any words in its input that are palindromes (read the same forwards and backwards). 6. Why not use the following in as the for loop in exercise 3? for (i = 0; i < strlen(word); i++) 8. Write a C function that takes a string as an argument and modifies the string so as to remove all consecutive duplicate characters, e.g., mississippi -> misisipi. 7. (a) Write a C program that takes a filename as a command line input, copies the contents of the file into a string, and prints the string. (b) Modify your solution to part (a) so that it discards all characters except {a, c, g, t} when copying into the string. (c) Modify your solution to part (a) so that it discards all characters except {A, B, ..., Y} when copying into the string. 7. Write a C program that takes an integer and a file name as command line inputs, and prints out all instances in the file where the number of consecutive occurrences of some character is greater than the given integer. . . ANSWERS TO EXERCISES ON STRINGS 0. The point of this exercise is that characters are represented as integers in C. The actual values depend on the system; in ASCII, 65 represents the character 'A', and 48 represents the character '0'. 'A' : A 65 '8' : 8 56 70 : B 66 'A' + 2 : C 67 n = 528 1. They all do. A. string library function, K+R page 250 B. K+R page 39 C. i isn't used until after the statement anyway D. K+R page 99 E. Sedgewick, page 114 F. Sedgewick, page 114 G. K+R page 103 2. Can't increment array name. Have to copy into pointer as in 1.D. Note also that this program assumes the input is 100 characters or less. You can use scanf("%100s", a) to ensure this. 3. Prints out all the words in the standard input whose characters appear in decreasing order. % a.out my wife tried dancing the polka but everyone laughed 4 wife 5 tried 3 the 5 polka % a.out < /usr/dict/words | grep 6 6 sponge % a.out < ~cs126/files/wordlist.txt | grep 7 7 sponged 7 wronged /usr/dict/words and ~cs126/files/wordlist.txt are files containing lists of English words. The Unix command 'grep 6 filename' prints all lines in the file that contain '6'. 4. void printPigLatinWord(char word[]) { printf("%s", word + 1); /* print word except first character */ printf("%c", word[0]); /* print first character of word */ printf("ay\n"); /* print "ay" */ } 5. Replace the for loop in the program of exercise 3 with for (i = 0; i < N; i++) if (word[i] != word[N-1-i]) break; This solution is twice as slow as it could be: we could stop the for loop in the middle. Exercise: fix the program to do so. % a.out ifihadahifi 11 ifihadahifi % a.out < ~cs126/files/wordlist.txt | grep 7 7 deedeed 7 murdrum 7 repaper 7 reviver 7 rotator 7 sooloos 6. Calls strlen() every time through the loop. Takes time proportional to the square of the length of the string. There are plenty of C programs out there that are extremely slow for long strings because of this bug. 8. void remove_duplicates(char word[]) { int i, j; char prev = '\0'; for (i = j = 0; word[i] != '\0'; i++) { if (prev != word[i]) word[j++] = word[i]; prev = word[i]; } word[j] = '\0'; } 7. (a) #include #include #include #define MAX_LEN 10000 int main(int argc, char *argv[]) { int c, i; char a[MAX_LEN + 1]; FILE *filename = fopen(argv[1], "r"); if(filename == NULL) { printf("Error opening file.\n"); exit(EXIT_FAILURE); } i = 0; while ((c = getc(filename)) != EOF) a[i++]; a[i] = '\0'; fclose(filename); printf("%s\n", a); return 0; } 7. (b) Modify the while loop as follows. while ((c = getc(filename)) != EOF) if (c == 'a' || c == 'c' || c == 'g' || c == 't') a[i++]; 7. (c) Modify the while loop as follows. Be sure to #include for the isupper() function. while ((c = getc(filename)) != EOF) if (isupper(c) && c != 'Z') a[i++]; 7. #include int main(int argc, char *argv[]) { int i, j, c, prev; int max = atoi(argv[1]); FILE *text = fopen(argv[2], "r"); for (i = 0, j = 0; (c = getc(text)) != EOF; i++, j++, prev = c) if (c != prev) { if (j > max) printf ("%2d %c's at %d\n", j, prev, i - j); j = 0; } return 0; }