You are on page 1of 39

Solution Manual for Absolute C++, 5/E 5th Edition

Walter Savitch

To download the complete and accurate content document, go to:


https://testbankbell.com/download/solution-manual-for-absolute-c-5-e-5th-edition-walt
er-savitch/
Solution Manual for Absolute C++, 5/E 5th Edition Walter Savitch

Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Chapter 7
Constructors and Other Tools
Key Terms
constructor
initialization section
default constructor
constant parameter
const with member functions
inline function
static variable
initializing static member variables
nested class
local class
vector
declaring a vector variable
template class
v[i]
push_back
size
size unsigned int
capacity

Brief Outline
7.1 Constructors
Constructor Definitions
Explicit Constructor Calls
Class Type Member Variables
7.2 More Tools
The const Parameter Modifier
Inline Functions
Static Members
Nested and Local Class Definitions
7.3 Vectors – A Preview of the Standard Template Library
Vector Basics
Efficiency Issues.

1. Introduction and Teaching Suggestions


Tools developed in this chapter are the notion of const member functions, inline functions, static
members, nested classes and composition. A const member function is a promise not to change
state of the calling object. A call to an inline function requests that the compiler put the body of
the function in the code stream instead of a function call. A static member of a class is

ScholarStock

Visit TestBankBell.com to get complete for all chapters


Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

connected to the class rather than being connected to specific object. The chapter ends with a
brief introduction to the vector container and a preview of the STL.

Students should immediately see the comparison of vectors to arrays and note how it is generally
much easier to work with vectors. In particular, the ability to grow and shrink makes it a much
easier dynamic data structure while the use of generics allows vectors to store arbitrary data
types. If you have given assignments or examples with traditional arrays then it may be
instructive to re-do those same programs with vectors instead.

2. Key Points
Constructor Definitions. A constructor is a member function having the same name as the
class. The purpose of a class constructor is automatic allocation and initialization of resources
involved in the definition of class objects. Constructors are called automatically at definition of
class objects. Special declarator syntax for constructors uses the class name followed by a
parameter list but there is no return type.

Constructor initialization section. The implementation of the constructor can have an


initialization section:
A::A():a(0), b(1){ /* implementation */ }
The text calls the :a(0), b(1) the initialization section. In the literature, this sometimes
called a member initializer list. The purpose of a member initializer list is to initialize the class
data members. Only constructors may have member initializer lists. Much of the time you can
initialize the class members by assignment within the constructor block, but there are a few
situations where this is not possible. In these cases you must use an initialization section, and the
error messages are not particularly clear. Encourage your students to use initialization sections in
preference to assignment in the block of a constructor. Move initialization from the member
initializer list to the body of the constructor when there is a need to verify argument values.

Class Type Member Variables. A class may be used like any other type, including as a type of
a member of another class. This is one of places where you must use the initializer list to do
initialization.

The const Parameter Modifier. Reference parameters that are declared const provide
automatic error checking against changing the caller’s argument. All uses of the const modifier
make a promise to the compiler that you will not change something and a request for the
compiler to hold you to your promise. The text points out that the use of a call-by-value
parameter protects the caller’s argument against change. Call-by-value copies the caller’s
argument, hence for a large type can consume undesirable amounts of memory. Call-by-
reference, on the other hand, passes only the address of the caller’s argument, so consumes little
space. However, call-by-reference entails the danger of an undesired change in the caller’s
argument. A const call-by-reference parameter provides a space efficient, read-only parameter
passing mechanism.

A const call-by-value parameter mechanism, while legal, provides little more than an annoyance
to the programmer.

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

The const modifier appended to the declaration of a member function in a class definition is a
promise not to write code in the implementation that will change the state of the class. Note that
the const modifier on the function member is part of the signature of a class member function
and is required in both declaration and definition if it is used in either.

The const modifier applied to a return type is a promise not to do anything the returned object to
change it. If the returned type is a const reference, the programmer is promising not to use the
call as an l-value. If the returned type is a const class type, the programmer is promising not to
apply any non-const member function to the returned object.

Inline Functions. Placing the keyword inline before the declaration of a function is a hint to the
compiler to put body of the function in the code stream at the place of the call (with arguments
appropriately substituted for the parameters). The compiler may or may not do this, and some
compilers have strong restrictions on what function bodies will be placed inline.

Static Members. The keyword static is used in several contexts. C used the keyword static
with an otherwise global declaration to restrict visibility of the declaration from within other
files. This use is deprecated in the C++ Standard.. In Chapter 11, we will see that unnamed
namespaces replace this use of static.

In a function, a local variable that has been declared with the keyword static is allocated once
and initialized once, unlike other local variables that are allocated and initialized (on the system
stack) once per invocation. Any initialization is executed only once, at the time the execution
stream reaches the initialization. Subsequently, the initialization is skipped and the variable
retains its value from the previous invocation.

The third use of static is the one where a class member variable or function is declared with the
static keyword. The definition of a member as static parallels the use of static for function local
variables. There is only one member, associated with the class (not replicated for each object).

Nested and Local Classes. A class may be defined inside another class. Such a class is in the
scope of the outer class and is intended for local use. This can be useful with data structures
covered in Chapter 17.

Vectors. The STL vector container is a generalization of array. A vector is a container that is
able to grow (and shrink) during program execution. A container is an object that can contain
other objects. The STL vector container is implemented using a template class (Chapter 16). The
text’s approach is to define some vector objects and use them prior to dealing with templates and
the STL in detail (Chapter 19). Unlike arrays, vector objects can be assigned, and the behavior is
what you want. Similar to an array, you can declare a vector to have a 10 elements initialized
with the default constructor by writing
vector<baseType> v(10);
Like arrays, objects stored in a vector object can be accessed for use as an l-value or as an r-
value using indexing.
v[2] = 3;
x = v[0];

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Unlike arrays, however, you cannot (legally) index into a vector, say v[i], to fetch a value or to
assign a value unless an element has already been inserted at every index position up to and
including index position i. The push_back(elem) function can be used to add an element to
the end of a vector.

Efficiency Issues for Vectors. Most implementations of vector have an array that holds its
elements. The array is divided into that used for elements that have been inserted, and the rest is
called reserve. There is a member function that can be used to adjust the reserve up or down.
Implementations vary with regard to whether the reserve member can decrease the capacity of a
vector below the current capacity.

3. Tips
Invoking constructors. You cannot call a constructor as if it were a member function, but
frequently it is useful to invoke a constructor explicitly. In fact this declaration of class A in
object u :
A u(3);
is short hand for
A u = A(3);
Here, we have explicitly invoked the class A constructor that can take an int argument. When we
need to build a class object for return from a function, we can explicitly invoke a constructor.
A f()
{
int i;
// compute a value for i
return A(i);
}

Always Include a Default Constructor. A default constructor will automatically be created for
you if you do not define one, but it will not do anything. However, if your class definition
includes one or more constructors of any kind, no constructor is generated automatically.

Static member variables must be initialized outside the class definition. Static variables may
be initialized only once, and they must be initialized outside the class definition.. The text points
out that the class author is expected to do the initializations, typically in the same file where the
class definition appears.
Example:
class A
{
public:
A();
. . .
private:
static int a;
int b;

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

};
int A::a = 0; // initialization

A static member is intended to reduce the need for global variables by providing alternatives that
are local to a class. A static member function or variable acts as a global for members of its class
without being available to, or clashing with, global variables or functions or names of members
of other classes.

A static member function is not supplied with the implicit “this” pointer that points to the
instance of a class. Consequently, a static member function can only use nested types,
enumerators, and static members directly. To access a non-static member of its class, a static
member function must use the . or the -> operator with some instance (presumably passed to
the static member function via a parameter).

4. Pitfalls
Attempting to invoke a constructor like a member function. We cannot call a constructor for
a class as if it were a member of the class.

Constructors with No Arguments. It is important not to use any parentheses when you declare
a class variable and want the constructor invoked with no arguments, e.g.
MyClass obj;
instead of
MyClass obj();
Otherwise, the compiler sees it as a prototype declaration of a function that has no parameters
and a return type of MyClass.

Inconsistent Use of const. If you use const for one parameter of a particular type, then you
should use it for every other parameter that has that type and is not changed by the function call.

Attempt to access non-static variables from static functions. Non-static class instance
variables are only created when an object has been created and is therefore out of the scope of a
static function. Static functions should only access static class variables. However, non-static
functions can access static class variables.

Declaring An Array of class objects Requires a Default Constructor. When an array of class
objects is defined, the default constructor is called for each element of the array, in increasing
index order. You cannot declare an array of class objects if the class does not provide a default
constructor.

There is no array bounds checking done by a vector. There is a member function,


at(index) that does do bounds checking. When you access or write an element outside the
index range 0 to (size-1), is undefined. Otherwise if you try to access v[i] where I is greater than
the vector’s size, you may or may not get an error message but the program will undoubtedly
misbehave.

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

5. Programming Projects Answers


1. Class Month
Notes:

Abstract data type for month.


Need:
Default constructor
constructor to set month using first 3 letters as 3 args
constructor to set month using int value : 1 for Jan etc

input function (from keyboard) that sets month from 1st 3 letters of month name
input function (from keyboard) that sets month from int value : 1 for Jan etc
output function that outputs (to screen) month as 1st 3 letters in the name of the month (C-
string?)
output function that outputs (to screen) month as number, 1 for Jan etc.
member function that returns the next month as a value of type Month.

.int monthNo; // 1 for January, 2 for February etc

Embed in a main function and test.

//file: ch7prb1.cpp
//Title: Month
//To create and test a month ADT

#include <iostream>
#include <cstdlib> // for exit()
#include <cctype> // for tolower()

using namespace std;

class Month
{
public:
//constructor to set month based on first 3 chars of the month name
Month(char c1, char c2, char c3); // done, debugged
//a constructor to set month base on month number, 1 = January etc.
Month( int monthNumber); // done, debugged
//a default constructor (what does it do? nothing)
Month(); // done, no debugging to do
//an input function to set the month based on the month number
void getMonthByNumber(istream&); // done, debugged
//input function to set the month based on a three character input
void getMonthByName(istream&); // done, debugged
//an output function that outputs the month as an integer,
void outputMonthNumber(ostream&); // done, debugged
//an output function that outputs the month as the letters.
void outputMonthName(ostream&); // done, debugged
//a function that returns the next month as a month object

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Month nextMonth(); //
//NB: each input and output function have a single formal parameter
//for the stream

int monthNumber();

private:
int mnth;
};

//added
int Month::monthNumber()
{
return mnth;
}

Month Month::nextMonth()
{
int nextMonth = mnth + 1;
if (nextMonth == 13)
nextMonth = 1;
return Month(nextMonth);
}

Month::Month( int monthNumber)


{
mnth = monthNumber;
}

void Month::outputMonthNumber( ostream& out )


{
//cout << "The current month is "; // only for debugging
out << mnth;
}
// This implementation could profit greatly from use of an array!
void Month::outputMonthName(ostream& out)
{
// a switch is called for. We don't have one yet!
if (1 == mnth) out << "Jan";
else if (2 == mnth) out << "Feb";
else if (3 == mnth) out << "Mar";
else if (4 == mnth) out << "Apr";
else if (5 == mnth) out << "May";
else if (6 == mnth) out << "Jun ";
else if (7 == mnth) out << "Jul ";
else if (8 == mnth) out << "Aug";
else if (9 == mnth) out << "Sep";
else if (10 == mnth) out << "Oct";
else if (11 == mnth) out << "Nov";
else if (12 == mnth) out << "Dec";
}
void error(char c1, char c2, char c3)
{
cout << endl << c1 << c2 << c3 << " is not a month. Exiting\n";
exit(1);
}
void error(int n)

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

{
cout << endl << n << " is not a month number. Exiting" << endl;
exit(1);
}
void Month::getMonthByNumber(istream& in)
{
in >> mnth; // int Month::mnth;
}
// use of an array and linear search could help this implementation.
void Month::getMonthByName(istream& in)
{
// Calls error(...) which exits, if the month name is wrong.
// An enhancement would be to allow the user to fix this.
char c1, c2, c3;
in >> c1 >> c2 >> c3;
c1 = tolower(c1); //force to lower case so any case
c2 = tolower(c2); //the user enters is acceptable
c3 = tolower(c3);

if('j' == c1)
if('a' == c2)
mnth = 1; // jan
else
if ('u' == c2)
if('n' == c3)
mnth = 6; // jun
else if ('l' == c3)
mnth = 7; // jul
else error(c1, c2, c3); // ju, not n or
else error(c1, c2, c3); // j, not a or u
else
if('f' == c1)
if('e' == c2)
if('b' == c3)
mnth = 2; // feb
else error(c1, c2, c3); // fe, not b
else error(c1, c2, c3); // f, not e
else
if('m' == c1)
if('a' == c2)
if('y' == c3)
mnth = 5; // may
else
if('r' == c3)
mnth = 3; // mar
else error(c1, c2, c3); // ma not a, r
else error(c1,c2,c3); // m not a or r
else
if('a' == c1)
if('p' == c2)
if('r' == c3)
mnth = 4; // apr
else error(c1, c2, c3 ); // ap not r
else
if('u' == c2)
if('g' == c3)
mnth = 8; // aug

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

else error(c1,c2,c3); // au not g


else error(c1,c2,c3); // a not u or p
else
if('s' == c1)
if('e' == c2)
if('p' == c3)
mnth = 9; // sep
else error(c1, c2, c3); // se, not p
else error(c1, c2, c3); // s, not e
else
if('o' == c1)
if('c' == c2)
if('t' == c3)
mnth = 10; // oct
else error(c1, c2, c3); // oc, not t
else error(c1, c2, c3); // o, not c
else
if('n' == c1)
if('o' == c2)
if('v' == c3)
mnth = 11; // nov
else error(c1, c2, c3); // no, not v
else error(c1, c2, c3); // n, not o
else
if('d' == c1)
if('e' == c2)
if('c' == c3)
mnth = 12; // dec
else error(c1, c2, c3);// de, not c
else error(c1, c2, c3);// d, not e
else error(c1, c2, c3);//c1,not j,f,m,a,s,o,n,or d
}
Month::Month(char c1, char c2, char c3)
{
c1 = tolower(c1);
c2 = tolower(c2);
c3 = tolower(c3);
if('j' == c1)
if('a' == c2)
mnth=1; // jan
else if ('u' == c2)
if('n' == c3)
mnth = 6; // jun
else if('l' == c3)
mnth = 7; // jul
else error(c1, c2, c3); // ju, not n or
else error(c1, c2, c3); // j, not a or u
else if('f' == c1)
if('e' == c2)
if('b' == c3)
mnth = 2; // feb
else error(c1, c2, c3); // fe, not b
else error(c1, c2, c3); // f, not e
else
if('m' == c1)
if('a' == c2)
if('y' == c3)

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

mnth = 5; // may
else
if('r' == c3)
mnth = 3; // mar
else error(c1, c2, c3); // ma not a, r
else error(c1,c2,c3); // m not a or r
else
if('a' == c1)
if('p' == c2)
if('r' == c3)
mnth = 4; // apr
else error(c1, c2, c3 ); // ap not r
else
if('u' == c2)
if('g' == c3)
mnth = 8; // aug
else error(c1,c2,c3); // au not g
else error(c1,c2,c3); // a not u or p
else
if('s' == c1)
if('e' == c2)
if('p' == c3)
mnth = 9; // sep
else error(c1, c2, c3); // se, not p
else error(c1, c2, c3); // s, not e
else
if('o' == c1)
if('c' == c2)
if('t' == c3)
mnth = 10; // oct
else error(c1, c2, c3); // oc, not t
else error(c1, c2, c3); // o, not c
else
if('n' == c1)
if('o' == c2)
if('v' == c3)
mnth = 11; // nov
else error(c1, c2, c3); // no, not v
else error(c1, c2, c3); // n, not o
else
if('d' == c1)
if('e' == c2)
if('c' == c3)
mnth = 12; // dec
else error(c1, c2, c3); // de, not c
else error(c1, c2, c3); // d, not e
else error(c1, c2, c3);//c1 not j,f,m,a,s,o,n,or d
}
Month::Month()
{
// body deliberately empty
}

int main()
{
cout << "testing constructor Month(char, char, char)" << endl;

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Month m;
m = Month( 'j', 'a', 'n');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'f', 'e', 'b');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'm', 'a', 'r');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'a', 'p', 'r');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'm', 'a', 'y');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'j', 'u', 'n');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'j', 'u', 'l');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'a', 'u', 'g');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 's', 'e', 'p');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'o', 'c', 't');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'n', 'o', 'v');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
m = Month( 'd', 'e', 'c');
m.outputMonthNumber( cout ); cout << " ";
m.outputMonthName(cout); cout << endl;
cout << endl << "Testing Month(int) constructor" << endl;
int i = 1;
while (i <= 12)
{
Month mm(i);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}
cout << endl
<< "Testing the getMonthByName and outputMonth* \n";
i = 1;
Month mm;
while (i <= 12)
{
mm.getMonthByName(cin);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << endl


<< "Testing getMonthByNumber and outputMonth* " << endl;
i = 1;
while (i <= 12)
{
mm.getMonthByNumber(cin);
mm.outputMonthNumber( cout ); cout << " ";
mm.outputMonthName(cout); cout << endl;
i = i+1;
}
cout << endl << "end of loops" << endl;
cout << endl << "Testing nextMonth member" << endl;
cout << "current month ";
mm.outputMonthNumber(cout); cout << endl;
cout << "next month ";
mm.nextMonth().outputMonthNumber(cout); cout << " ";
mm.nextMonth().outputMonthName(cout); cout << endl;
cout << endl << "new Month created " << endl;
Month mo(6);
cout << "current month ";
mo.outputMonthNumber(cout); cout << endl;
cout << "nextMonth ";
mo.nextMonth().outputMonthNumber(cout); cout << " ";
mo.nextMonth().outputMonthName(cout); cout << endl;
return 0;
}

/*
A partial testing run follows:
$a.out
testing constructor Month(char, char, char)
1 Jan
2 Feb
3 Mar
4 Apr
5 May
6 Jun
7 Jul
8 Aug
9 Sep
10 Oct
11 Nov
12 Dec
Testing Month(int) constructor
1 Jan

Remainder of test run omitted


*/
\

2. Redefinition of class Month


Same as #1, except state is now the 3 char variables containing the first 3 letters of month name.
Variant: Use C-string to hold month.
Variant 2: Use vector of char to hold month. This has more promise.

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

3. “Little Red Grocery Store Counter”


A good place to start is with the solution to #2 from Chapter 6.

The class counter should provide:


A default constructor. For example, Counter(9999); provides a counter that can count up
to 9999 and displays 0.
A member function, void reset() that returns count to 0
A set of functions that increment digits 1 through 4:
void incr1() //increments 1 cent digit
void incr10() //increments 10 cent digit
void incr100() //increments 100 cent ($1) digit
void incr1000() //increments 1000 cent ($10)digit
Account for carries as necessary.
A member function bool overflow(); detects overflow.
Use the class to simulate the little red grocery store money counter.
Display the 4 digits, the right most two are cents and tens of cents, the next to are dollars and
tens of dollars.
Provide keys for incrementing cents, dimes, dollars and tens of dollars.
Suggestion: asdfo: a for cents, followed by 1-9
s for dimes, followed by 1-9
d for dollars, followed by 1-9
f for tens of dollars, followed by 1-9
Followed by pressing the return key in each case.
Adding is automatic, and overflow is reported after each operation. Overflow can be requested
with the O key.
Here is a tested implementation of this simulation.

You will probably need to adjust the PAUSE_CONSTANT for your machine, otherwise the
pause can be so short as to be useless, or irritatingly long.
//Ch7prg3.cpp
//
//Simulate a counter with a button for each digit.
//Keys a for units
// s for tens, follow with digit 1-9
// d for hundreds, follow with digit 1-9
// f for thousands, follow with digit 1-9
// o for overflow report.
//
//Test thoroughly
//
//class Counter
//
// default constructor that initializes the counter to 0
// and overflowFlag to 0
// member functions:
// reset() sets count to 0 and overflowFlag to false

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// 4 mutators each of which increment one of the 4 digits.


// (carry is accounted for)
// bool overflow() returns true if last operation resulted in
// overflow.
// 4 accessors to display each digit
// a display function to display all 4 digits
//
//
// The class keeps a non-negative integer value.
// It has an accessor that returns the count value,
// and a display member that write the current count value
// to the screen.

#include <iostream>
using namespace std;

const int PAUSE_CONSTANT = 100000000; // 1e8


void pause(); // you may need to adjust PAUSE_CONSTANT

class Counter
{
public:
Counter();

//mutators
void reset();
void incr1();
void incr10();
void incr100();
void incr1000();

//accessors
void displayUnits();
void displayTens();
void displayHundreds();
void displayThousands();

int currentCount();
void display();

bool overflow();

private:
int units;
int tens;
int hundreds;
int thousands;
bool overflowFlag;
};
int main()
{
int i;
int j; // digit to follow "asdf"
char ch;

Counter c;
int k = 100;

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

while(k-- > 0)
{
system("cls");
//system("clear");

if(c.overflow())
cout << "ALERT: OVERFLOW HAS OCCURRED. RESULTS "
<< "ARE NOT RELIABLE. Press Q to quit.\n";

cout << endl;


c.displayThousands(); c.displayHundreds();
cout << ".";
c.displayTens(); c.displayUnits();
cout << endl;
cout << "Enter a character followed by a digit 1-9:\n"
<< "Enter a for units\n"
<< " s for tens\n"
<< " d for hundreds\n"
<< " f for thousands\n"
<< " o to inquire about overflow\n"
<< "Q or q at any time to quit.\n";
cin >> ch;

//vet value of ch, other housekeeping


if(ch != 'a' && ch != 's' && ch != 'd' && ch != 'f')
{
if(ch == 'Q' || ch == 'q')
{
cout << ch << " pressed. Quitting\n";
return 0;
}

if(ch == 'o')
{ cout << "Overflow test requested\n";
if(c.overflow())
{
cout << "OVERFLOW HAS OCCURRED. RESULTS "
<< "ARE NOT RELIABLE. Press Q to quit.\n";
}
pause();
continue; //restart loop
}
cout << "Character entered not one of a, s, d, f, or o.\n";
pause();
continue; //restart loop.
}

cin >> j;
// vet value of j
if( !(0 < j && j <= 9))
{
cout << "Digit must be between 1 and 9\n";
continue;
}

switch(ch)
{

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

case 'a': for(i = 0; i < j; i++)


c.incr1();
break;
case 's': for(i = 0; i < j; i++)
c.incr10();
break;

case 'd': for(i = 0; i < j; i++)


c.incr100();
break;

case 'f': for(i = 0; i < j; i++)


c.incr1000();
break;
case 'Q': // fall through
case 'q': cout << "Quitting\n";
return 0; // quit.

default: cout << "Program should never get here\n"


<< "Fix program\n";
abort();
}
cout << "At end of switch \n";
}

return 0;
}

// Implementations

void pause()
{
cout << "Pausing for you to read . . .\n";
for(int X = 0; X < PAUSE_CONSTANT; X++)
{
X++; X--;
}
}
void Counter::displayUnits()
{
cout << units;
}
void Counter::displayTens()
{
cout << tens;
}
void Counter::displayHundreds()
{
cout << hundreds;
}
void Counter::displayThousands()
{
cout << thousands;
}

void Counter::reset()
{

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

units = tens = hundreds = thousands = 0;


overflowFlag = false;
}

void Counter::display()
{
cout << thousands << hundreds
<< tens << units ;
}

bool Counter::overflow()
{
return overflowFlag;
}

Counter::Counter():units(0), tens(0), hundreds(0),


thousands(0), overflowFlag(false)
{// body deliberately empty
}

void Counter::incr1()
{
if(units < 9)
units++;
else
{
units = 0;
if(tens < 9)
tens++;
else
{
tens = 0;
if(hundreds < 9)
hundreds++;
else
{
hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
}
}

void Counter::incr10()
{
if(tens < 9)
tens++;
else
{
tens = 0;
if(hundreds < 9)
hundreds++;
else
{

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
}

void Counter::incr100()
{
if(hundreds < 9)
hundreds++;
else
{
hundreds = 0;
if(thousands < 9)
thousands++;
else
overflowFlag = true;
}
}
void Counter::incr1000()
{
if(thousands < 9)
thousands++;
else
{
thousands = 0;
overflowFlag = true;
}
}

4. Hot Dogs
You operate several hot dog stands distributed throughout town. Definite a class named
HotDogStand that has a member variable for the hot dog stand's ID number and a member
variable for how many hot dogs the stand has sold that day. Create a constructor that allows a
user of the class to initialize both values.

Also create a method named "JustSold" that increments the number of hot dogs the stand has
sold by one. The idea is that this method will be invoked each time the stand sells a hot dog so
that we can track the total number of hot dogs sold by the stand. Add another method that
returns the number of hot dogs sold.

Finally, add a static variable that tracks the total number of hotdogs sold by all hot dog stands
and a static method that returns the value in this variable.

Write a main method to test your class with at least three hot dog stands that each sell a variety
of hot dogs.

CodeMate Hint: Recall that static variables must be initialized outside of the class definition.

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

//hotdogs.cpp
//This program defines a class for tracking hot dog sales.
//
//It tracks the stand's ID number, hot dogs sold at each stand,
// and hot dogs sold at all stands.

#include <iostream>
#include <cstdlib>

using namespace std;

class HotDogStand
{
public:
HotDogStand();
HotDogStand(int newID, int newNnumSold);
int GetID();
void SetID(int newID);
void JustSold();
int GetNumSold();
static int GetTotalSold();

private:
static int totalSold;
int numSold;
int ID;
};

int HotDogStand::totalSold = 0;

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

// ======================
// HotDogStand::HotDogStand
// The default constructor initializes the ID and num sold to zero.
// ======================
HotDogStand::HotDogStand()
{
numSold = 0;
ID = 0;
}

// ======================
// HotDogStand::HotDogStand
// This constructor initializes the ID and num sold.
// ======================
HotDogStand::HotDogStand(int newID, int newNumSold)
{
numSold = newNumSold;
ID = newID;
}

// ======================

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// HotDogStand::GetID
// Returns the ID number of this stand.
// ======================
int HotDogStand::GetID()
{
return ID;
}

// ======================
// HotDogStand::SetID
// Sets the ID number of this stand.
// ======================
void HotDogStand::SetID(int newID)
{
ID = newID;
}

// ======================
// HotDogStand::JustSold
// Increments the number of hotdogs this stand
// has sold by one.
// ======================
void HotDogStand::JustSold()
{
numSold++; // increment number sold at this stand
totalSold++; // increment number sold across all stands
}

// ======================
// HotDogStand::GetNumSold
// Returns the number of hotdogs this stand has sold.
// ======================
int HotDogStand::GetNumSold()
{
return numSold;
}

// ======================
// HotDogStand::GeTotalSold
// Returns the number of hotdogs sold by all stands
// ======================
int HotDogStand::GetTotalSold()
{
return totalSold;
}

//
// --------------------------------
// --------- END USER CODE --------
// --------------------------------

// ======================
// main function
// ======================

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

int main()
{
// Test our code with three hot dog stands
HotDogStand s1(1,0),s2(2,0),s3(3,0);

// Sold at stand 1, 2
s1.JustSold();
s2.JustSold();
s1.JustSold();

cout << "Stand " << s1.GetID() << " sold " << s1.GetNumSold() << endl;
cout << "Stand " << s2.GetID() << " sold " << s2.GetNumSold() << endl;
cout << "Stand " << s3.GetID() << " sold " << s3.GetNumSold() << endl;
cout << "Total sold = " << s1.GetTotalSold() << endl;
cout << endl;

// Sold some more


s3.JustSold();
s1.JustSold();

cout << "Stand " << s1.GetID() << " sold " << s1.GetNumSold() << endl;
cout << "Stand " << s2.GetID() << " sold " << s2.GetNumSold() << endl;
cout << "Stand " << s3.GetID() << " sold " << s3.GetNumSold() << endl;
cout << "Total sold = " << s1.GetTotalSold() << endl;
cout << endl;
return 0;
}

5. Suitors
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following
procedure to determine which suitor she would marry. First, all of the suitors would be lined up
one after the other and assigned numbers. The first suitor would be number 1, the second
number 2, and so on up to the last suitor, number n. Starting at the first suitor she would then
count three suitors down the line (because of the three letters in her name) and the third suitor
would be eliminated from winning her hand and removed from the line. Eve would then
continue, counting three more suitors, and eliminating every third suitor. When she reached the
end of the line she would continue counting from the beginning.

For example, if there were 6 suitors then the elimination process would proceed as follows:

123456 initial list of suitors, start counting from 1


12456 suitor 3 eliminated, continue counting from 4
1245 suitor 6 eliminated, continue counting from 1
125 suitor 4 eliminated, continue counting from 5
15 suitor 2 eliminated, continue counting from 5
1 suitor 5 eliminated, 1 is the lucky winner

Write a program that uses a vector to determine which position you should stand in to marry the
princess if there are n suitors. You will find the following method from the Vector class useful:

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

v.erase(iter);
// Removes element at position iter

For example, to use this method to erase the 4th element from the beginning of a vector variable
named theVector use:

theVector.erase(theVector.begin() + 3);

The number 3 is used since the first element in the vector is at index position 0.

CodeMate Hint: Use a vector of size n and a loop that continues to eliminate the next suitor until
the size of the vector includes only one element.

//suitors.cpp
//
//This program determines where to stand in line if you would
// like to win the hand of the princess. The princess eliminates
// every third suitor and loops back to the beginning of the line upon
// reaching the end.
//
//This program uses a vector to store the list of suitors and removes
// each one in turn.

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

// ======================
// main function
// ======================
int main()
{
// Variable declarations
int i;
int current;
int numSuitors;

cout << "Enter the number of suitors" << endl;


cin >> numSuitors;

vector<int> suitors(numSuitors);

for (int i=0; i<numSuitors; i++)


{
suitors[i] = i+1; // Number each suitor's position
}

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

if (numSuitors <=0)
{
cout << "Not enough suitors." << endl;
}
else if (numSuitors == 1)
{
cout << "You would stand first in line." << endl;
}
else
{
current=0; // Current suitor the princess will examine
// Eliminate a suitor as long as there is at least one
while (suitors.size() > 1)
{
// Count three people ahead, or go two people down
// since we include the current person in the count
for (i=0; i<2; i++)
{
current++;
// If we reached the end, go back to the front
if (current == suitors.size())
{
current=0;
}
}
// Eliminate contestant current
suitors.erase(suitors.begin() + current);
// If we were at the last suitor, go to the first one
if (current == suitors.size())
{
current=0;
}
}
cout << "To win the princess, you should stand in position " <<
suitors[0] << endl;
}

// --------------------------------
// --------- END USER CODE --------
// --------------------------------
return 0;
}

6. More Pizza
This Programming Project requires you to first complete Programming Project 7 from Chapter 5,
which is an implementation of a Pizza class. Add an Order class that contains a private vector
of type Pizza. This class represents a customer’s entire order, where the order may consist of
multiple pizzas. Include appropriate functions so that a user of the Order class can add pizzas to
the order (type is deep dish, hand tossed, or pan; size is small, medium, or large; number of
pepperoni or cheese toppings). You can use constants to represent the type and size. Also write
a function that outputs everything in the order along with the total price. Write a suitable test
program that adds multiple pizzas to an order(s).

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Notes: The following solution uses the pizza.h and pizza.cpp classes from Programming Project
7 of Chapter 5.
// order.h
//
// Interface file for the Pizza ordering class.

#include "pizza.h"
#include <vector>
#include <iostream>
using namespace std;

class Order
{
public:
Order();
~Order() {};
void addPizza(Pizza p);
void outputOrder();
private:
vector<Pizza> orders;
};

// order.cpp
//
// Implementation file for the Pizza ordering class.

#include "order.h"
#include <vector>
#include <iostream>
using namespace std;

Order::Order()
{
}

// --------------------------------
// ----- ENTER YOUR CODE HERE -----
// --------------------------------

void Order::addPizza(Pizza p)
{
orders.push_back(p);
}

void Order::outputOrder()
{
double total = 0;
cout << "There are " << orders.size() <<
" pizzas in the order." << endl;
for (int i=0; i<orders.size(); i++)
{
orders[i].outputDescription();
total += orders[i].computePrice();
}

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << "The total price is $" << total << endl;
}

// --------------------------------
// --------- END USER CODE --------
// --------------------------------

// ======================
// main function
// ======================
int main()
{
// Variable declarations
Order myOrder;
Pizza cheesy;
Pizza pepperoni;

// Make some pizzas


cheesy.setCheeseToppings(3);
cheesy.setType(HANDTOSSED);

pepperoni.setSize(LARGE);
pepperoni.setPepperoniToppings(2);
pepperoni.setType(PAN);

// Add to the order


myOrder.addPizza(cheesy);
myOrder.addPizza(pepperoni);

// Output order
myOrder.outputOrder();

cout << endl;


}

7. Money Constructor
Do Programming Project 6.8, the definition of a Money class, except create a default constructor
that sets the monetary amount to 0 dollars and 0 cents, and create a second constructor with input
parameters for the amount of the dollars and cents variables. Modify your test code to invoke the
constructors.
#include <iostream>
using namespace std;

class Money
{
public:
// Constructors
Money();
Money(int initialDollars, int initialCents);
// Functions
int getDollars();

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

int getCents();
void setDollars(int d);
void setCents(int c);
double getAmount();
private:
int dollars;
int cents;
};

Money::Money()
{
dollars = 0;
cents = 0;
}

Money::Money(int initialDollars, int initialCents) :


dollars(initialDollars), cents(initialCents)
{
}

int Money::getDollars()
{
return dollars;
}

int Money::getCents()
{
return cents;
}

void Money::setDollars(int d)
{
dollars = d;
}

void Money::setCents(int c)
{
cents = c;
}

double Money::getAmount()
{
return static_cast<double>(dollars) +
static_cast<double>(cents) / 100;
}

int main( )
{
Money m1(20, 35), m2(0, 98);

cout << m1.getDollars() << "." << m1.getCents() << endl;


cout << m1.getAmount() << endl;
cout << m2.getAmount() << endl;

cout << "Changing m1's dollars to 50" << endl;


m1.setDollars(50);
cout << m1.getAmount() << endl;

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout << "Enter a character to exit." << endl;


char wait;
cin >> wait;
return 0;
}

8. Histogram of Grades
Write a program that outputs a histogram of grades for an assignment given to a class of
students. The program should input each student’s grade as an integer and store the grade in a
vector. Grades should be entered until the user enters -1 for a grade. The program should then
scan through the vector and compute the histogram. In computing the histogram the minimum
value of a grade is 0 but your program should determine the maximum value entered by the user.
Output the histogram to the console. See Programming Project 5.7 for information on how to
compute a histogram.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
vector<int> grades;
int max = -1;
int score;
int i;

// Input grades until -1 is entered


cout << "Enter each grade and then -1 to stop." << endl;
do
{
cin >> score;
// Add to vector
if (score >= 0)
{
grades.push_back(score);
// Remember the largest value
if (score > max)
max = score;
}
} while (score != -1);

// Create histogram vector large enough to store the largest score


vector<int> histogram(max+1);
// Initialize histogram to 0
for (i=0; i<=max; i++)
{
histogram[i]=0;
}

// Loop through grades and increment histogram index


for (i=0; i<grades.size(); i++)

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

{
histogram[grades[i]]++;
}

// Output histogram
for (i=0; i<=max; i++)
{
cout << histogram[i] << " grade(s) of " << i << endl;
}
cout << endl;

cout << "Enter a character to exit." << endl;


char wait;
cin >> wait;
return 0;
}

9. POSTNET Bar Codes


The bar code on an envelope used by the US Postal Service represents a five (or more) digit zip
code using a format called POSTNET (this format is being deprecated in favor of a new system,
OneCode, in 2009). The bar code consists of long and short bars as shown below:

For this program we will represent the bar code as a string of digits. The digit 1 represents a
long bar and the digit 0 represents a short bar. Therefore, the bar code above would be
represented in our program as:

110100101000101011000010011

The first and last digits of the bar code are always 1. Removing these leave 25 digits. If these 25
digits are split into groups of five digits each then we have:

10100 10100 01010 11000 01001

Next, consider each group of five digits. There will always be exactly two 1’s in each group of
digits. Each digit stands for a number. From left to right the digits encode the values 7, 4, 2, 1,
and 0. Multiply the corresponding value with the digit and compute the sum to get the final
encoded digit for the zip code. The table below shows the encoding for 10100.
Bar Code 1 0 1 0 0
Digits
Value 7 4 2 1 0
Product of 7 0 2 0 0
Digit * Value
Zip Code Digit = 7 + 0 + 2 + 0 + 0 = 9

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

Repeat this for each group of five digits and concatenate to get the complete zip code. There is
one special value. If the sum of a group of five digits is 11, then this represents the digit 0 (this
is necessary because with two digits per group it is not possible to represent zero). The zip code
for the sample bar code decodes to 99504. While the POSTNET scheme may seem
unnecessarily complex, its design allows machines to detect if errors have been made in scanning
the zip code.

Write a zip code class that encodes and decodes five digit bar codes used by the US Postal
Service on envelopes. The class should have two constructors. The first constructor should
input the zip code as an integer and the second constructor should input the zip code as a bar
code string consisting of 0’s and 1’s as described above. Although you have two ways to input
the zip code, internally the class should only store the zip code using one format (you may
choose to store it as a bar code string or as a zip code number.) The class should also have at
least two public member functions, one to return the zip code as an integer, and the other to
return the zip code in bar code format as a string. All helper functions should be declared
private. Embed your class definition in a suitable test program.

#include <iostream>
#include <string>
using namespace std;

class ZipCode
{
public:
ZipCode(int zip);
// Constructs a ZipCode from an integer zip code value
ZipCode(string code);
// Constructs a ZipCode from a string of 1's and 0's
string get_bar_code();
// Returns the zip code in bar form
int get_zip_code();
// Returns the zip code in numeric form

private:
int zip;
int parse_bar_code(string code);
// Returns an integer, parsed from the given bar code.
// If the code is not valid, this function will print
// an error message and then exit.
};

// Constructs a ZipCode from an integer zip code value


ZipCode::ZipCode(int z) : zip(z)
{
}

// Constructs a ZipCode from a string of 1's and 0's


ZipCode::ZipCode(string code)
{
zip = parse_bar_code(code);
}

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

// Returns an integer, parsed from the given bar code.


// If the code is not valid, this function will print
// an error message and then exit.
int ZipCode::parse_bar_code(string code)
{
int value = 0;

if (((code.length() - 2) % 5) != 0)
{
cout << "ERROR: '" << code << "' has invalid length " << endl
<< " (Length must be 5*n+2, where n is the number of"
<< endl
<< " digits in the zip code)" << endl;
return -1;
}
else if ((code[0] != '1') || (code[code.length() - 1] != '1'))
{
cout << "ERROR: '" << code << "' must begin and end with '1'" << endl;
return -1;
}
else
{
int digits = (code.length() - 2)/5;

// Each position 0 - 5 in each 1/0 digit sequence has


// a unique value. Putting these in an array lets us
// map a digit position to a value by doing an array
// lookup, rather than an if-else-if statement.
int values[] = { 7, 4, 2, 1, 0 };

for (int d = 0; d < digits; d++)


{
int digit = 0;
for (int i = 0; i < 5; i++)
{
char ch = code[d * 5 + i + 1];
if (ch == '1')
{
digit += values[i];
}
else if (ch != '0')
{
cout << "ERROR: '" << code
<< "' must contain only '1' and '0'" << endl;
// exit(1);
return -1;
}
}

if ((digit < 1) || (digit == 10) || (digit > 11))


{
cout << "ERROR: '" << code << "' has invalid sequence '"
<< code.substr(d * 5 + 1, 5) << "'" << endl;
// exit(1);
return -1;
}

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

if (digit == 11)
{
digit = 0;
}

value = (value * 10) + digit;


}
}
return value;
}

// Returns the zip code in numeric form


int ZipCode::get_zip_code()
{
return zip;
}

// Returns the zip code in bar form


string ZipCode::get_bar_code()
{
string code;
int z, digit, numDigits, targetDigits;

// Each digit 0-9 has a unique 5-digit bar code sequence.


// If we put these in an array, then we can simply look
// them up via an array index.
string digits[] =
{ "11000", "00011", "00101", "00110", "01001",
"01010", "01100", "10001", "10010", "10100" };

z = zip;
numDigits = 0;

// Work backwards through the zip code integer


while (z > 0)
{
// Pull off the smallest digit
digit = (z % 10);

// Then throw that digit away


z = z/10;

// Prepend the digit to the code


code = digits[digit] + code;

numDigits++;
}

// Make sure we always have at least 5 or 9 digits (zip or zip+4)


if (numDigits > 5)
{
targetDigits = 9;
}
else
{
targetDigits = 5;

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

while (numDigits < targetDigits)


{
code = digits[0] + code;
numDigits++;
}

// Put a '1' on each end


return "1" + code + "1";
}

// MAIN FUNCTION
int main()
{
ZipCode zip(99504),
zip2("100101010011100001100110001"),
zip3(12345),
zip4(67890);
int BAD_ZIP_COUNT = 5;
string bad_zips[][2] = {
{ "10010101001110000110011001", "bad length" },
{ "000101010011100001100110001", "bad start/end character" },
{ "100101010011100001100110000", "bad start/end character" },
{ "100101010011100001100110021", "bad digit" },
{ "100101010011100001100111001", "bad sequence" }
};

cout << zip.get_zip_code() << "'s bar code is '"


<< zip.get_bar_code() << "'" << endl;
cout << zip2.get_zip_code() << "'s bar code is '"
<< zip2.get_bar_code() << "'" << endl;
cout << zip3.get_zip_code() << "'s bar code is '"
<< zip3.get_bar_code() << "'" << endl;
cout << zip4.get_zip_code() << "'s bar code is '"
<< zip4.get_bar_code() << "'" << endl;

cout << endl;

// Test a range of values by first constructing a zip code with


// an integer, then retrieving the bar code and using that to
// construct another ZipCode.
int zip_int = 0;
for (int i = 0; i < 25; i++)
{
// Make an aribrary 5-digit zip code integer, and use it
// to construct a ZipCode
int five_digit_zip = (zip_int * zip_int) % 100000;
ZipCode z1(five_digit_zip);

// Construct a second ZipCode from the first's bar code


string z1_code = z1.get_bar_code();
ZipCode z2(z1_code);

cout.width(3);
cout << (i + 1) << ": ";

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cout.width(5);
cout << z2.get_zip_code() << " has code '"
<< z1_code << "'";

if ((z1_code == z2.get_bar_code()) &&


(z1.get_zip_code() == z2.get_zip_code()) &&
(z2.get_zip_code() == five_digit_zip))
{
cout << " [OK]" << endl;
}
else
{
cout << " [ERR]" << endl;
}

// Increment the test value arbitrarily


zip_int += (233 + zip_int % 7);
}

cout << endl;

// Test some error conditions. This test assumes that


// ZipCode will simply set its value to a flag that indicates
// an error, and will not exit the program.
for (int i = 0; i < BAD_ZIP_COUNT; i++)
{
cout << "Testing: " << bad_zips[i][1] << endl;
ZipCode test(bad_zips[i][0]);
cout << endl;
}

cout << "Enter a character to quit." << endl;


char c;
cin >> c;
return 0;
}

10. Static variable in Box Of Produce


First, complete Programming Project 6.12. Modify the main function with a loop so that an
arbitrary number of BoxOfProduce objects are created and substitutions are allowed for each box.
Add a menu so the user can decide when to stop creating boxes.

You would like to throw in a free recipe flyer for salsa verde if the box contains tomatillos.
However, there are only 5 recipe flyers. Add a static member variable to the BoxOfProduce class
that counts the number of recipe flyers remaining and initialize it to 5. Also add a member
variable that indicates whether or not the box contains a recipe flyer and modify the output
function to also print "salsa verde recipe" if the box contains a recipe flyer. Finally, add logic
inside the class so that if the box contains at least one order of tomatillos then it automatically gets
a recipe flyer until all of the recipe flyers are gone. Note that a box should only get one recipe flyer
even if there are multiple orders of tomatillos.

Test your class by creating boxes with tomatillos from your menu until all of the flyers are gone.

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

// Max number of bundles in a box


const int MAX_BUNDLES = 100;

class BoxOfProduce
{
private:
int numBundles;
string bundle[MAX_BUNDLES];
bool hasSalsaFlyer;
void tomatilloCheck();
static int numSalsaFlyers;
public:
BoxOfProduce();
void initialize();
void addBundle(string b);
string getBundle(int index);
void setBundle(string b, int index);
string boxContents();
};

// Initialize the static variable


int BoxOfProduce::numSalsaFlyers = 5;

BoxOfProduce::BoxOfProduce()
{
initialize();
}

void BoxOfProduce::initialize()
{
numBundles = 0;
hasSalsaFlyer = false;
}

// If the bundle contains tomatillos and we have


// flyers left, then set the hasFlyer variable
// and subtract one from the number of flyers left.
// Once we have added a flyer to a box we don't
// remove it.
void BoxOfProduce::tomatilloCheck()
{
// If box has a flyer then exit
if (hasSalsaFlyer)
return;
// If no flyers left, then exit
if (numSalsaFlyers == 0)
return;

// Check if there are any tomatillos

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

for (int i = 0; i < numBundles; i++)


if (bundle[i] == "Tomatillo")
{
// Add salsa flyer
hasSalsaFlyer = true;
numSalsaFlyers--;
}
}

void BoxOfProduce::addBundle(string b)
{
if (numBundles < MAX_BUNDLES)
{
bundle[numBundles] = b;
numBundles++;
}
// Check if we should add a salsa flyer
tomatilloCheck();
}

string BoxOfProduce::getBundle(int index)


{
if ((index >=0) && (index < MAX_BUNDLES))
return bundle[index];
else
return "";
}

void BoxOfProduce::setBundle(string b, int index)


{
if ((index >=0) && (index < MAX_BUNDLES))
bundle[index] = b;
// Check if we should add a salsa flyer
tomatilloCheck();
}

string BoxOfProduce::boxContents()
{
string s = "The box contains: ";
for (int i = 0; i < numBundles; i++)
s = s + " (" + char('0'+i+1) + ")" + bundle[i];
if (hasSalsaFlyer)
s = s + ". Bonus - Salsa Verde Recipe Flyer";
return s;
}

int main()
{
char addMoreBoxes;
do
{
// Create a Box
BoxOfProduce box;
box.initialize();

// Initialize the random number generator

ScholarStock
Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

srand(time(NULL));
// Pick three random numbers from 0 to 4 for the 5 possible food
choices
int num1, num2, num3;
num1 = rand() % 5;
num2 = rand() % 5;
num3 = rand() % 5;

int lineRead = 0;
ifstream inputStream;
inputStream.open("produce.txt");

string food;
while (inputStream >> food)
{
if (lineRead == num1)
box.addBundle(food);
if (lineRead == num2)
box.addBundle(food);
if (lineRead == num3)
box.addBundle(food);
lineRead++;
}
inputStream.close();

// Show the box contents to the user and allow substitutions


char selection = ' ';
do
{
cout << box.boxContents() << endl;
cout << "Enter 'a' to add a new bundle." << endl;
cout << "Enter 'c' to change a bundle." << endl;
cout << "Enter 'q' to quit." << endl;
cin >> selection;
if (selection == 'a')
{
cout << "Enter item to add." << endl;
string item;
cin >> item;
box.addBundle(item);
}
else if (selection == 'c')
{
cout << "Enter index of item to change." << endl;
int i;
cin >> i;
cout << "Enter item to substitute." << endl;
string item;
cin >> item;
box.setBundle(item, i-1); // Index is 0 based so sub 1
}
} while (selection != 'q');
cout << "Final Contents:" << endl;
cout << box.boxContents() << endl;

cout << endl;


cout << "Add another box? (y/n)" << endl;

ScholarStock
Solution Manual for Absolute C++, 5/E 5th Edition Walter Savitch

Savitch, Absolute C++ 5/e: Chapter 7, Instructor’s Manual

cin >> addMoreBoxes;


} while (addMoreBoxes == 'y');
return 0;
}

ScholarStock

Visit TestBankBell.com to get complete for all chapters

You might also like