Answers to Self-Test Exercises 395 10. #include <cstring> //needed to get the declaration of strcpy strcpy(aString, "Hello"); 11. I did it my way! 12. The string "good, I hope." is too long for aString. A chunk of memory that doesn’t belong to the array aString will be overwritten. 13. The complete dialogue is as follows: Enter some input: The time is now. The-time<END OF OUTPUT 14. The complete dialogue is as follows: Enter a line of input: May the hair on your toes grow long and curly. May t<END OF OUTPUT 15. The complete dialogue is as follows: Enter a line of input: a b c d e f g a b END OF OUTPUT 16. The complete dialogue is as follows: Enter a line of input: abcdef gh ace h Note that the output is simply every other character of the input, and note that the blank is treated just like any other character. 17. The complete dialogue is as follows: Enter a line of input: 0 1 2 3 4 5 6 7 8 9 10 11 01234567891 1 Be sure to note that only the ’1’ in the input string 10 is output. This is because cin.get is reading characters, not numbers, and so it reads the input 10 as the two characters ’1’ and ’0’. Since this code is written to echo only every other character, the ’0’ is not output. Since the ’0’ is not output, the next character, which is a blank, is output, and so there is one blank in the output. Similarly, only one of the two ’1’ characters in 11 is output. If this is unclear, write the input on a sheet of paper and use a small square for the blank character. Then, cross out every other character; the output shown above is what is left. 09_CH09.fm Page 395 Wednesday, August 13, 2003 1:04 PM 396 Strings 18. This code contains an infinite loop and will continue as long as the user continues to give it input. The Boolean expression (next != ’\n’) is always true because next is filled via the statement cin >> next; and this statement always skips the newline character, ’\n’ (as well as any blanks). The code will run, and if the user gives no additional input, the dialogue will be as follows: Enter a line of input: 0 1 2 3 4 5 6 7 8 9 10 11 0246811 This code outputs every other nonblank character. The two ’1’ characters in the output are the first character in the input 10 and the first character in the input 11. 19. The complete dialogue is as follows: Enter a line of input: I’ll see you at 10:30 AM. I’ll see you at 1<END OF OUTPUT 20. cout << "Enter a line of input:\n"; char next; do { cin.get(next); if (!isupper(next)) cout << next; } while (next != ’\n’); Note that you should use !isupper(next) and not use islower(next). This is because islower(next) returns false if next contains a character that is not a letter (such as the blank or comma symbol). 21. //Uses iostream: void newLine( ) { cin.ignore(10000, ’\n’); } Of course, this only works for lines less than about 10,000 characters, but any lines longer than that would likely indicate some other unrelated problem. 22. A*string<END OF OUTPUT 23. A string is a joy forever!<END OF OUTPUT 09_CH09.fm Page 396 Wednesday, August 13, 2003 1:04 PM Programming Projects 397 24. The complete dialogue is as follows: Enter a line of input: Hello friend! Equal 25. Hello Jello PROGRAMMING PROJECTS 1. Write a program that will read in a sentence of up to 100 characters and output the sen- tence with spacing corrected and with letters corrected for capitalization. In other words, in the output sentence all strings of two or more blanks should be compressed to a single blank. The sentence should start with an uppercase letter but should contain no other uppercase letters. Do not worry about proper names; if their first letter is changed to lower- case, that is acceptable. Treat a line break as if it were a blank in the sense that a line break and any number of blanks are compressed to a single blank. Assume that the sentence ends with a period and contains no other periods. For example, the input the Answer to life, the Universe, and everything IS 42. should produce the following output: The answer to life, the universe, and everything is 42. 2. Write a program that will read in a line of text and output the number of words in the line and the number of occurrences of each letter. Define a word to be any string of letters that is delimited at each end by either whitespace, a period, a comma, or the beginning or end of the line. You can assume that the input consists entirely of letters, whitespace, commas, and periods. When outputting the number of letters that occur in a line, be sure to count uppercase and lowercase versions of a letter as the same letter. Output the letters in alpha- betical order and list only those letters that occur in the input line. For example, the input line I say Hi. should produce output similar to the following: 3 words 1 a 1 h 2 i 1 s 1 y 09_CH09.fm Page 397 Wednesday, August 13, 2003 1:04 PM 398 Strings 3. Write a program that reads a person’s name in the following format: first name, then mid- dle name or initial, and then last name. The program then outputs the name in the follow- ing format: Last_Name, First_Name, Middle_Initial. For example, the input Mary Average User should produce the output User, Mary A. The input Mary A. User should also produce the output User, Mary A. Your program should place a period after the middle initial even if the input did not con- tain a period. Your program should allow for users who give no middle name or middle ini- tial. In that case, the output, of course, contains no middle name or initial. For example, the input Mary User should produce the output User, Mary If you are using C-strings, assume that each name is at most 20 characters long. Alterna- tively, use the class string. (Hint: You may want to use three string variables rather than one large string variable for the input. You may find it easier to not use getline.) 4. Write a program that reads in a line of text and replaces all four-letter words with the word "love". For example, the input string I hate you, you dodo! should produce the output: I love you, you love! Of course, the output will not always make sense. For example, the input string John will run home. 09_CH09.fm Page 398 Wednesday, August 13, 2003 1:04 PM Programming Projects 399 should produce the output: Love love run love. If the four-letter word starts with a capital letter, it should be replaced by "Love", not by "love". You need not check capitalization, except for the first letter of a word. A word is any string consisting of the letters of the alphabet and delimited at each end by a blank, the end of the line, or any other character that is not a letter. Your program should repeat this action until the user says to quit. 5. Write a program that can be used to train the user to use less sexist language by suggesting alternative versions of sentences given by the user. The program will ask for a sentence, read the sentence into a string variable, and replace all occurrences of masculine pro- nouns with gender-neutral pronouns. For example, it will replace "he" by "she or he". Thus, the input sentence See an adviser, talk to him, and listen to him. should produce the following suggested changed version of the sentence: See an adviser, talk to her or him, and listen to her or him. Be sure to preserve uppercase letters for the first word of the sentence. The pronoun "his" can be replaced by "her(s)"; your program need not decide between "her" and "hers". Allow the user to repeat this for more sentences until the user says she or he is done. This will be a long program that requires a good deal of patience. Your program should not replace the string "he" when it occurs inside another word such as "here". A word is any string consist- ing of the letters of the alphabet and delimited at each end by a blank, the end of the line, or any other character that is not a letter. Allow your sentences to be up to 100 characters long. 6. There is a CD available for purchase that contains .jpeg and .gif images of music that is in the public domain. The CD includes a file consisting of lines containing the names, then composers of that title, one per line. The name of the piece is first, then zero or more spaces then a dash (-) character, then one or more spaces, then the composer’s name. The com- poser name may be only last name, or an initial and one name, or two names: first last, or three names: first middle last. There are a few tunes with “no author listed” as author. In the subsequent processing, “no author listed” should not be rearranged. Here is a very abbreviated list of the titles and authors. 1. Adagio “MoonLight” Sonata - Ludwig Van Beethoven 2. An Alexis - F.H. Hummel and J.N. Hummel 3. A La Bien Aimee- Ben Schutt 4. At Sunset- E. MacDowell 5. Angelus- J. Massenet 6. Anitra’s Dance- Edward Grieg 7. Ase’s Death- Edward Grieg 8. Au Matin- Benj. - Godard . . . 09_CH09.fm Page 399 Wednesday, August 13, 2003 1:04 PM 400 Strings 37. The Dying Poet - L. Gottschalk 38. Dead March - G.F. Handel 39. Do They Think of Me At Home - Chas. W. Glover 40. The Dearest Spot - W.T. Wrighton 1. Evening - L. Van Beethoven 2. Embarrassment - Franz Abt 3. Erin is my Home - no author listed 4. Ellen Bayne - Stephen C. Foster . . . 9. Alla Mazurka- A. Nemerowsky . . . 1. The Dying Volunteer - A.E. Muse 2. Dolly Day - Stephen C. Foster 3. Dolcy Jones - Stephen C. Foster 4. Dickory, Dickory, Dock - no author listed 5. The Dear Little Shamrock - no author listed 6. Dutch Warbler - no author listed . . . The ultimate task is to produce an alphabetized list of composers followed by a list of pieces by them alphabetized on the title within composer. This exercise is easier if it is broken into pieces: Write code to: a. Remove the lead numbers, any periods, and any spaces so that the first word of the title is the first word of the line. b. Replace any multiple spaces with a single space. c. A few titles may have several - characters, for example: 20. Ba- Be- Bi- Bo- Bu - no author listed Replace all dash - characters on any line before the end of the line by a space except the last one. d. The last word in the title may have the - character with no space between it and the = character. Put the space in. e. When alphabetizing the title, you don’t want to consider an initial “A”, “An”, or “The” in the title. Write code to move such initial words to just before the - character. A comma after the last word in the title is not required, but that would be a nice touch. This can be done after the composer’s names are moved to the front, but obviously the code will be different. f. Move the composer’s names to the beginning of the line, followed by the - character, followed by the composition title. g. Move any first initial, first and second names of the composer to after the composer’s last name. If the composer is “no author listed” this should not be rearranged, so test for this combination. 09_CH09.fm Page 400 Wednesday, August 13, 2003 1:04 PM Programming Projects 401 h. Alphabetize by composer using any sort routine you know. You may ignore any duplicate composer’s last name, such as CPE Bach and JS Bach, but sorting by composer’s second name would be a nice touch. You may use the insertion sort, or selection sort, or bubble sort, or other sorting algorithm. i. If you have not already done so, move “A”, “An”, or “The” that may begin a title to the end of the title. Then alphabetize within each composer by composition title. j. Keep a copy of your design and your code. You will be asked to do this over using the STL vector container. 09_CH09.fm Page 401 Wednesday, August 13, 2003 1:04 PM 10 Pointers and Dynamic Arrays 10.1 POINTERS 404 Pointer Variables 405 Basic Memory Management 414 Pitfall: Dangling Pointers 416 Dynamic Variables and Automatic Variables 416 Tip: Define Pointer Types 417 Pitfall: Pointers as Call-by-Value Parameters 419 Uses for Pointers 421 10.2 DYNAMIC ARRAYS 422 Array Variables and Pointer Variables 422 Creating and Using Dynamic Arrays 423 Example: A Function That Returns an Array 427 Pointer Arithmetic 429 Multidimensional Dynamic Arrays 430 10.3 CLASSES, POINTERS, AND DYNAMIC ARRAYS 433 The -> Operator 433 The this Pointer 434 Overloading the Assignment Operator 435 Example: A Class for Partially Filled Arrays 437 Destructors 445 Copy Constructors 446 CHAPTER SUMMARY 451 ANSWERS TO SELF-TEST EXERCISES 452 PROGRAMMING PROJECTS 454 10 Pointers and Dynamic Arrays Memory is necessary for all the operations of reason. Blaise Pascal, Pensées INTRODUCTION A pointer is a construct that gives you more control of the computer’s memory. This chapter will show you how pointers are used with arrays and will intro- duce a new form of array called a dynamically allocated array. Dynamically allocated arrays (dynamic arrays for short) are arrays whose size is determined while the program is running, rather than being fixed when the program is written. Before reading Sections 10.1 and 10.2 on pointers and dynamically allo- cated arrays you should first read Chapters 1 through 6 (omitting the coverage of vectors if you wish), but you need not read any of Chapters 7 through 9. You can even read Sections 10.1 and 10.2 after reading just Chapters 1 to 5, provided you ignore the few passages that mention classes. Section 10.3 discusses some tools for classes that only become relevant once you begin to use pointers and dynamically allocated data (such as dynamically allocated arrays). Before covering Section 10.3, you should read Chapters 1 through 8, although you may omit the coverage of vectors if you wish. You may cover this chapter, Chapter 11 on separate compilation and namespaces, Chapter 12 on file I/O, and Chapter 13 on recursion in any order. If you do not read the Chapter 11 section on namespaces before this chapter, you might find it profitable to review the section of Chapter 1 enti- tled “Namespaces.” Pointers By indirections find directions out. William Shakespeare, Hamlet A pointer is the memory address of a variable. Recall from Chapter 5 that the computer’s memory is divided into numbered memory locations (called bytes ) and that variables are implemented as a sequence of adjacent memory loca- tions. Recall also that sometimes the C++ system uses these memory addresses as names for the variables. If a variable is implemented as, say, three memory locations, then the address of the first of these memory locations is sometimes 10.1 Pointers 405 used as a name for that variable. For example, when the variable is used as a call-by- reference argument, it is this address, not the identifier name of the variable, that is passed to the calling function. An address that is used to name a variable in this way (by giving the address in memory where the variable starts) is called a pointer because the address can be thought of as “pointing” to the variable. The address “points” to the vari- able because it identifies the variable by telling where the variable is, rather than telling what the variable’s name is. You have already been using pointers in a number of situations. As noted in the pre- vious paragraph, when a variable is a call-by-reference argument in a function call, the function is given this argument variable in the form of a pointer to the variable. As noted in Chapter 5, an array is given to a function (or to anything else, for that matter) by giving a pointer to the first array element. (At the time we called these pointers “memory addresses,” but that is the same thing as a pointer.) These are two powerful uses for pointers, but they are handled automatically by the C++ system. This chapter shows you how to write programs that directly manipulate pointers rather than relying on the system to manipulate the pointers for you. ■ POINTER VARIABLES A pointer can be stored in a variable. However, even though a pointer is a memory address and a memory address is a number, you cannot store a pointer in a variable of type int or double . A variable to hold a pointer must be declared to have a pointer type. For example, the following declares p to be a pointer variable that can hold one pointer that points to a variable of type double : double *p; The variable p can hold pointers to variables of type double , but it cannot normally contain a pointer to a variable of some other type, such as int or char . Each variable type requires a different pointer type. 1 In general, to declare a variable that can hold pointers to other variables of a specific type, you declare the pointer variable just as you would declare an ordinary variable of that type, but you place an asterisk in front of the variable name. For example, the fol- lowing declares the variables p1 and p2 so they can hold pointers to variables of type int ; it also declares two ordinary variables v1 and v2 of type int : int *p1, *p2, v1, v2; There must be an asterisk before each of the pointer variables. If you omit the second asterisk in the above declaration, then p2 will not be a pointer variable; it will instead be an ordinary variable of type int . 1 There are ways to get a pointer of one type into a pointer variable for another type, but it does not happen automatically and is very poor style anyway. declaring pointer variables . August 13, 2003 1:04 PM 400 Strings 37. The Dying Poet - L. Gottschalk 38. Dead March - G.F. Handel 39. Do They Think of Me At Home - Chas. W. Glover 40. The Dearest Spot - W.T. Wrighton 1. Evening. the STL vector container. 09_CH09.fm Page 401 Wednesday, August 13, 2003 1:04 PM 10 Pointers and Dynamic Arrays 10.1 POINTERS 404 Pointer Variables 405 Basic Memory Management 414 Pitfall:. not be rearranged, so test for this combination. 09_CH09.fm Page 400 Wednesday, August 13, 2003 1:04 PM Programming Projects 401 h. Alphabetize by composer using any sort routine you know. You