Exercise 5-7
Given the implementation of frame in S5.8.1/93, and the following code fragment
vector<string> v; frame(v);
describe what happens in this call. In particular, trace through how both the width function and the frame function operate. Now, run this code. If the results differ from your expectations, first understand why your expectations and the program differ, and then change one to match the other.
Solution
The frame function has a return type of vector<string>. To “frame” the vector<string> v means to pad all the string elements within v to the full optimum width as defined by the width function. (i.e. the length of the longest string element in v).
My expectation of running this code fragment:
- The first statement of the code fragment creates an empty vector<string> v.
- The second statement of the code fragment attempts to frame this empty vector<string> v.
- When we apply frame(v), the width function returns a maxlen of 0 (i.e. the initialised maxlen value) – i.e. implying no elements in v.
- The frame function by default however, always return a top and bottom border of four asterisks (*). So even though the for loop within the frame function processes an empty vector<string> v, at a minimum, frame(v) should return the top and bottom borders. i.e. element 0 contains “****”, and element 1 contains “****”. This is it!
If we however populate the vector<string> v with some elements, the frame function should behave as demonstrated in the text book Chapter 5, or Solution to Exercise 5-0 (Part 3/3). i.e. equal length string elements with width of at least 5. e.g. if vector<string> v contains just one string element “a”, then, frame(v) will return:
- element 0: “*****”
- element 1:”* a *” (note there is a space around the string element)
- element 2: “*****
Test Program
Though we have used the frame function multiple times in the previous exercises already, for completeness sake I shall include my test program here and run a couple of tests, for prove of concept purposes – to confirm the test result agrees with my expectation.
main.cpp
#include <iostream> #include <string> // string #include <vector> // vector #include <algorithm> // max using std::string; using std::vector; using std::max; using std::cin; using std::cout; using std::endl; string::size_type width(const vector<string>& v) { string::size_type maxlen = 0; for(vector<string>::size_type i = 0; i != v.size(); ++i) maxlen = max(maxlen, v[i].size()); return maxlen; } vector<string> frame(const vector<string>& v) { vector<string> ret; string::size_type maxlen = width(v); string border(maxlen + 4, '*'); // write the top border ret.push_back(border); // write each interior row, bordered by an asterisk and a space for (vector<string>::size_type i = 0; i != v.size(); ++i) ret.push_back("* " + v[i] + string(maxlen - v[i].size(), ' ') + " *"); // write the bottom border ret.push_back(border); return ret; } int main() { string s; // line vector<string> v; // paragraph while (getline(cin, s)) v.push_back(s); vector<string> framedV = frame(v); for (vector<string>::const_iterator iter = framedV.begin(); iter != framedV.end(); ++iter) { cout << (*iter) << endl; } return 0; }
Test 1 – empty vector<string> v
As expected, if we frame an empty vector<string> v, by default the frame function should return the top and bottom border at the minimum default width of four asterisks (*).
^Z **** ****
Test 2 – non-empty vector<string> v
If we frame a non-empty vector<string> v, the output should be just as described in Chapter 5 – equal length string elements, with the width determined by the longest string (line) element.
This is a test over over ^Z ************* * This is * * a test * * over over * *************
Let’s do one more. Let’s verify our expectation if we only submit a string element “a”.
a ^Z ***** * a * *****
Bingo!
Johnny,
The statement
frame(v);
ignores the return value of vector. I’m not sure what was going through Koenig & Moo’s minds when they wrote the question.
Yeah. After completing 5-5 and making a center() function that uses width(), what is the point of this question?
I think the point of the question was line 47. I imagine they thought the reader would assume that the code would print the framed picture and then come to realize that the function was called but the return value was never stored and processed. Definitely an odd question.