Chapter 4 – Organizing Programs and Data

Solutions to exercises in Chapter 4 of Accelerated C++, “Organizing programs and data.”

Exercise 4-1

We noted in §4.2.3/65 that it is essential that the argument types in a call to max match exactly. Will the following code work? If there is a problem, how would you fix it?

expand/collapse icon Hint

Consider the return type of s.name.size().

expand/collapse icon Solution

There is a problem with the code. The type returned from s.name.size() is string::size_type, which does not match the type of maxlen. To solve the problem, change maxlen‘s declaration to string::size_type.

Exercise 4-2

Write a program to calculate the squares of int values up to 100. The program should write two columns: The first lists the value; the second contains the square of that value. Use setw to manage the output so that the values line up in columns.

expand/collapse icon Hint

Determine the widest outputs for both columns.

expand/collapse icon Solution

The widest number that is being squared is 100, which is three digits. 100 squared is 10000, which is 5 digits, so the solution belows sets a width of 4 prior to sending the base to output and set a width of 6 prior to sending the result to output. Setting the widths one larger than the values contained will preserve at least one space to the left of each value.

When executed the output will look like the following (shortened for space):

Exercise 4-3

What happens if we rewrite the previous program to allow values up to but not including 1000 but neglect to change the arguments to setw? Rewrite the program to be more robust in the face of changes that allow i to grow without adjusting the setw arguments.

expand/collapse icon Hint

Determine the length of the longest base and longest result and store those maximum lengths before starting to send the results to output.

expand/collapse icon Solution

If we change the program to output squares of bases up to 999 but don’t change the values provided to setw, the columns will begin to run together when the number of digits in the squares begins to equal 6.

There are several ways to solve this problem, and in later chapters you will learn about some facilities in the standard library that would help you discover the maximum lengths that you need to find. This solution implements a function, digits, that will return the number of digits in an integer. The program uses this function to find the length of the maximum base and the length of the square of the maximum base. It saves these lengths and uses them as parameters to setw.

When executed the output will look like the following (shortened for space):

Exercise 4-4

Now change your squares program to use double values instead of ints. Use manipulators to manage the output so that the values line up in columns.

expand/collapse icon Hint

Allow for fractional values, and change how you determine the number of digits in the highest base and square.

expand/collapse icon Solution

First, we’ll make a change to the digits function to allow for the number of decimal places we want to see on the final outputs. Next, we’ll use the setprecision manipulator to control the number of significant digits in the output.

When executed the output will look like the following (shortened for space):

Exercise 4-5

Write a function that reads words from an input stream and stores them in a vector. Use that function both to write programs that count the number of words in the input, and to count how many times each word occurred.

expand/collapse icon Hint

Review the implementation of read_hw in §4.1.3. Then, learn how to use separate compilation with your particular compiler.

expand/collapse icon Solution

This exercise asks for two programs that perform two different tasks sharing a single function. That suggest that we should partition the programs as described in §4.4.

First, create a header that declares the shared function’s signature.

Next, implement the read_words function in a source file.

Now the programs can use this implementation. The first program will create a vector of strings and call read_words, passing cin and the vector as parameters. The populated vector will return the number of words it contains from its size() function.

The second program borrows from the solution to exercise 3-3.

Exercise 4-6

Rewrite the Student_info structure, and the read and grade functions, so that they calculate each student’s grades as part of reading the input, and store only the final grade.

expand/collapse icon No Solution Yet…

Check back for the solution later.

Exercise 4-7

Write a program to calculate the average of the numbers stored in a vector<double>.

expand/collapse icon No Solution Yet…

Check back for the solution later.

Exercise 4-8

If the following code is legal, what can we infer about the return type of f?

expand/collapse icon No Solution Yet…

Check back for the solution later.

Share

9 Comments

  1. Hi,

    thanks for these solutions, i have a question about the exercise 4-5, the second program will only count how many times the first word occurred ? and then why did we sort the words ?

    thanks !!

    • This function will read all the words in the vector. We just initialize the currentWord to the first entry in the vector to have an entry to compare to. So the first thing that happens in the for loop is to check if the currentWord (which is the first entry in the vector) is not equal to the next entry in the vector. The reason we use the sort function is that we are only comparing entries that are next to each other in the vector (we are iterating through the vector one entry(index) at a time and comparing the current entry to the previous entry.) If we didn’t arrange the words alphabetically, this algorithm would not work. Try it…remove the call to the sort function and see what happens.

      Hope this helps

  2. Hello,

    The Chapter 4 code in 4.1 does not seem to work in My Visual C++ 2010 express compiler so i was wondering what i could do, i have fixed it myself but it is not as good as it could be. Any Ideas?

    Thank You.

  3. I actually discovered another solution to Chapter 4 Ex 5 that uses less memory than the one listed here. The difference is really irrelevant for a program this small, and this is as far I’ve gotten in the book so I have no clue if it will be relevant later. But here it is if anyone’s curious!

    Just to say how redundant the difference is. Mine uses 40bytes regardless of the input (on my virtual machine running Slackware with netbeans). While the listed one uses 40bytes until you enter the input, in which case it spikes up depending on how much you input.

    Yes, that’s right, there’s not even a kilobyte of difference :p

    [code]
    #include “read_words.h”
    #include
    #include
    #include
    #include

    using std::cin;
    using std::cout;
    using std::endl;
    using std::sort;
    using std::string;
    using std::vector;

    int main()
    {
    vector words;

    cout << "Enter a few words, followed by end-of-file: " << endl;;

    if (read_words(cin, words))
    {
    typedef vector::size_type vec_sz;
    vec_sz size = words.size();

    // Check that the user entered some words
    if (size == 0)
    {
    cout << endl << "You didn't enter any words. "
    "Please try again." << endl;
    return 1;
    }

    // sort the words
    sort(words.begin(), words.end());

    string current_word;
    int count;

    // Set the initial word to the first word in the vector
    current_word = words[0];

    // Set the initial count for the first word
    count = 1;

    // Invariant: we have counted current_index of the total words
    // in the vector
    for (vec_sz current_index = 1; current_index < size; ++current_index)
    {
    // Report the count for the current word if it does not match
    // the word at the current index in the vector, and reset the
    // count to zero so that it will one when the variable is
    // incremented outside the if statement.
    if (current_word != words[current_index])
    {
    cout << "The word \"" << current_word << "\" appears "
    << count << " times." << endl;

    current_word = words[current_index];
    count = 0;
    }

    ++count;
    }

    // Report the count for the final word
    cout << "The word \"" << current_word << "\" appears "
    << count << " times." << endl;

    }
    else
    {
    cout << "An error occurred during input." << endl;
    return 2;
    }

    // We have reported the count of all the words in the vector, so exit.
    return 0;
    }
    [/code]

    • I copied the wrong code, herp derp.

      #include
      #include
      #include
      #include
      #include “read_words.h”
      using std::cin; using std::cout; using std::string;
      using std::vector; using std::endl; using std::sort;

      int main()
      {
      vector words;

      cout << "Input a few words, followed by end-of-file: ";

      if (read_words(cin, words))
      {
      typedef vector::size_type vec_sz;
      vec_sz size = words.size();

      // Confirm there have been words input
      if (size == 0)
      {
      cout << endl << "No words have been input. Please try again"
      << endl;

      return 1;
      }

      sort(words.begin(), words.end());

      vec_sz current_word = 0;

      // Invariant: We have counted current_index of the words in the vector
      for (vec_sz current_index = 1; current_index < size; ++current_index)
      {
      // When words [current_index] no longer is the same as
      // words[current_word], output the amount of times
      // words[current_word] was used by subtracting it from
      // words[current_index]
      if (words[current_index] != words[current_word])
      {
      cout << "The word\"" << words[current_word] << "\" appears "
      << current_index – current_word << " time(s)." << endl;

      current_word = current_index;
      }

      }
      // Report the final word
      cout << "The word\"" << words[current_word] << "\" appears "
      << size – current_word << " time(s)." << endl;
      }
      else
      {
      cout << "An error occurred during output." << endl;

      return 2;
      }

      return 0;
      }

Leave a Reply

Your email address will not be published. Required fields are marked *

*