Download as pdf or txt
Download as pdf or txt
You are on page 1of 138

Problem Solving with C++ 9th Edition

Savitch Solutions Manual


Go to download the full and correct content document:
https://testbankdeal.com/product/problem-solving-with-c-9th-edition-savitch-solutions-
manual/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Problem Solving with C++ 9th Edition Savitch Test Bank

https://testbankdeal.com/product/problem-solving-with-c-9th-
edition-savitch-test-bank/

Problem Solving with C++ 10th Edition Savitch Solutions


Manual

https://testbankdeal.com/product/problem-solving-with-c-10th-
edition-savitch-solutions-manual/

Problem Solving with C++ 10th Edition Savitch Test Bank

https://testbankdeal.com/product/problem-solving-with-c-10th-
edition-savitch-test-bank/

Engineering Problem Solving With C++ 4th Edition Etter


Solutions Manual

https://testbankdeal.com/product/engineering-problem-solving-
with-c-4th-edition-etter-solutions-manual/
Engineering Problem Solving With C++ 4th Edition Etter
Test Bank

https://testbankdeal.com/product/engineering-problem-solving-
with-c-4th-edition-etter-test-bank/

Data Abstraction And Problem Solving With C++ Walls And


Mirrors 6th Edition Carrano Solutions Manual

https://testbankdeal.com/product/data-abstraction-and-problem-
solving-with-c-walls-and-mirrors-6th-edition-carrano-solutions-
manual/

Data Abstraction and Problem Solving with C++ Walls and


Mirrors 7th Edition Carrano Solutions Manual

https://testbankdeal.com/product/data-abstraction-and-problem-
solving-with-c-walls-and-mirrors-7th-edition-carrano-solutions-
manual/

Data Abstraction And Problem Solving With C++ Walls And


Mirrors 6th Edition Carrano Test Bank

https://testbankdeal.com/product/data-abstraction-and-problem-
solving-with-c-walls-and-mirrors-6th-edition-carrano-test-bank/

Data Abstraction and Problem Solving with C++ Walls and


Mirrors 7th Edition Carrano Test Bank

https://testbankdeal.com/product/data-abstraction-and-problem-
solving-with-c-walls-and-mirrors-7th-edition-carrano-test-bank/
Chapter 7

ARRAYS

1. Solutions to and Remarks on Selected Practice Programs and


Programming Projects

Regarding the solutions presented here.: C++ leaves many options on how to do a problem,
and any book will necessarily choose a subset to present. It is necessary to read the text, as
that is what the student has to work with. I am striving to produce a complementary
document to the text, a document for the instructor. Most of the time, will use the
initialization list style for constructors. If you present the code using the initializer list, you
should also assign Appendix 7 on constructor initialization.

Programming Project 1: Rainfall

Here, I have done the interactive version only. The solution is broken into two files. The
source for each is listed, along with test data, command generating the output and the
output.

I have done the solution using structs here. The enhancement of adding the choice of
graphical output is provided. I have done only the interactive version here. The variation
using file i/o is left to the reader. Notes will be supplied for doing this without the struct.

//Author indicates that this may be done without structs or


//classes. This is a solution using structs.

//Program is to
//1)read in long term month by month average rain fall
// averages
//2)read in the previous year's month by month actual rain
// fall.

1
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//Output:
//'nicely' formatted table showing rainfall for each of the
// previous
//12 months as well as how much above or below the monthly
// average the rainfall is for each month. The output
// should correctly label months.
//
//Month name handling: code months as integers and do a
//conversion at output. Any input scheme acceptable as long
//as the user interface is relatively easy to use.

//Remarks: If the current month is April, we don't have


//April's rainfall figure yet, so we go back to April of the
//previous year, to March of this year.

//Enhanced version:
//Add capability to print two bar graphs for each month,
//showing the average rainfall and the actual rainfall for
//each of the previous 12 months. Ask the user's preference:
//a table or a graph, and display the format requested.
//
//Provide a loop to repeat the process at the user's request.

//Command line compile, where g++ is replaced by BCC32


//or CL –GX or CC depending on which compiler you use.
//g++ Ch10Prg1.cpp Ch10Prg1.bargraph.cpp

#include <iostream>
#include <cstring>

2
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

#include <cstdlib>

struct monthly_rain
{
int month;
double rain_fall;
double avg_rain_fall;
};

//declaration of function from file Ch10Prg1.bargraph.cpp


void output_bargraph( monthly_rain rainfall[],
int current_month );
//output: scale and bargraph of month by month average and
//actual rainfall.

void input( monthly_rain rainfall[], int& year );


//precondition:
//routine called correctly, with variable arguments
//postcondition:
//User is asked for current month, then is asked for
//the average and actual rainfall for each of the
//preceding 12 months.

void output_table( monthly_rain rainfall[], int& year );


//Precondition:
//input is array of size 12 of monthly_rain structs.
//Postcondition: output to screen is formatted table showing
//rainfall for each of the previous 12 months as well as how
//much above or below the monthly average the rainfall

3
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//for each month. The output should correctly label months.

int main()
{
using namespace std;
int current_month;
monthly_rain rainfall[12];
char ans;
char tg;
do
{
input( rainfall, current_month);
cout << "Please choose between g)raphical and t)abular "
<< "output" << endl;
cin >> tg; //tg means table/graphics choice :)

if ( 't' == tg || 'T' == tg )
{
cout << "You chose the tabular output." << endl;
output_table( rainfall, current_month );
}
else if ( 'g' == tg || 'G' == tg )
{
cout << "You chose the graphical output" << endl;
output_bargraph( rainfall, current_month);
}
else
{
cout << "You typed neither of the choices. "

4
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

<< "Defaulting to graphical output." << endl;


output_bargraph( rainfall, current_month );
}
cout << "Y/y continues, any thing else quits";
cin >> ans;
}while( 'y' == ans || 'Y' == ans );
return 0;
}

void full_month_name(int);

void input( monthly_rain rainfall[], int& current_month)


{
using namespace std;
int i;
cout << "\nMonthly rainfall input routine."
<< endl << endl
<< "Please enter the average rainfall for each month "
<< endl;

cout << " Average rainfall: " << endl;


for ( i = 0; i < 12; i++)
{
cout << "For month ";
full_month_name(i);
cout << ' ';
cin >> rainfall[i].avg_rain_fall;
cout << " \t Avg Rainfall: "
<< rainfall[i].avg_rain_fall;

5
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

rainfall[i].month = i;
cout << endl;
}

cout << endl << "The actual rainfall: " << endl;
cout << "What is the current month? Please give the "
<< "number of the month (Jan = 0, etc." << endl;

cin >> current_month;


cout << " The current month is: " ;
full_month_name(current_month);
cout << endl;

cout << "Please enter the actual rainfall for "


<< "each month, as prompted, First for the\n"
<< "months in the previous year: "
<< endl;

for ( i = current_month; i < 12; i++)


{
cout << "For month ";
full_month_name(i);
cout << " ";
cin >> rainfall[i].rain_fall;
cout << "\tRainfall: " << rainfall[i].rain_fall;
cout << endl;
}
cout << "Now for the months in this year: " << endl;
for ( i = 0; i < current_month; i++)

6
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
cout << "For month ";
full_month_name(i);
cout << ' ';
cin >> rainfall[i].rain_fall;
cout << "\tRainfall: " << rainfall[i].rain_fall;
cout << endl;
}

} //end of input routine

//helping routines for output_table, defined at the end of


//this file.
void month_name( int month );
void full_month_name( int month);

void output_table(monthly_rain rainfall[],


int& current_month)
{
using namespace std;
int i;
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(1);
//heading: Monthly Rainfall
// For the 12 Months Preceding .....
// Actual, Average, and Difference (= Actual - Average)

cout << "\t\t\t\t Monthly Rainfall " << endl;

7
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << "\t\t\tFor the 12 Months Preceding ";


full_month_name( current_month );
cout << endl;
cout << "\t\tActual, Average, and Difference "
<< " (= Actual - Average)" << endl;

cout << "\t-----+-----+-----+-----+-----+-----+-----"


<< "+-----+-----+-----+-----+----" << endl << "\t ";

for ( i = 0; i < 11; i++ )


{
month_name(rainfall[i].month);
cout << " | ";
}
month_name( rainfall[i].month );
cout << endl
<< "\t-----+-----+-----+-----+-----+-----+-----+"
<< "-----+-----+-----+-----+----"<< endl;

cout << "average\t";


for ( i = 0; i < 11; i++ )
{
cout.width(4);
cout << rainfall[i].rain_fall << " |";
}
cout.width(4);
cout << rainfall[i].rain_fall << endl;
cout << "actual\t";
for ( i = 0; i < 11; i++ )

8
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
cout.width(4);
cout << rainfall[i].avg_rain_fall << " |";
}
cout.width(4);
cout << rainfall[i].avg_rain_fall << endl;

cout << "diffs\t";


for ( i = 0; i < 11; i++ )
{
cout.width(4);
cout << rainfall[i].rain_fall - rainfall[i].avg_rain_fall
<< " |";
}
cout.width(4);
cout << rainfall[i].rain_fall - rainfall[i].avg_rain_fall
<< endl;

cout << "P)rev yr";


for ( i = 0; i < current_month; i++)
cout << " |";
for ( i = current_month; i < 11; i++)
cout << " P |" ;
cout << " P" << endl << endl;
}

void month_name( int month )


{
switch (month)

9
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
case 0: cout << "Jan";
break;
case 1: cout << "Feb";
break;
case 2: cout << "Mar";
break;
case 3: cout << "Apr";
break;
case 4: cout << "May";
break;
case 5: cout << "Jun";
break;
case 6: cout << "Jul";
break;
case 7: cout << "Aug";
break;
case 8: cout << "Sep";
break;
case 9: cout << "Oct";
break;
case 10: cout << "Nov";
break;
case 11: cout << "Dec";
break;
default: cout << "NO SUCH MONTH " << month << endl;
exit(1);
}
}

10
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void full_month_name( int month )


{
switch (month)
{
case 0: cout << "January "; //strings padded to 9 spaces
break; //for output formatting
case 1: cout << "February";
break;
case 2: cout << "March " ;
break;
case 3: cout << "April ";
break;
case 4: cout << "May ";
break;
case 5: cout << "June ";
break;
case 6: cout << "July ";
break;
case 7: cout << "August ";
break;
case 8: cout << "September";
break;
case 9: cout << "October ";
break;
case 10: cout << "November";
break;
case 11: cout << "December";
break;

11
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

default: cout << "NO SUCH MONTH " << month << endl;
exit(1);
}
}

//file: Ch7Prg1.bargraph.cpp
//
//to print two bargraphs for each month, showing average and
//actual rainfall each month.

#include <iostream>

struct monthly_rain
{
int month;
double rain_fall;
double avg_rain_fall;
};

void full_month_name( int );


void month_name( int );

//outputs x asterisks, no <cr>


void bargraph( double x )
{
using namespace std;
cout << " ";
for (int i = 0; i < x*10; i++)

12
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << '*';


}

//output scale followed by <cr>


//
void output_scale()
{
using namespace std;
cout << "\nRainfall ";
for ( int i = 0; i < 14; i++)
{
double j = i/2.0;
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(1);
cout << j << " ";
}
cout << endl << "\t ";
for (i = 0; i < 14; i++)
cout << "|****";
cout << endl;
}

void output_bargraph( monthly_rain rainfall[],


int current_month )
{
using namespace std;
output_scale();
for ( int i = 0; i < 12; i++ )

13
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
full_month_name( i );
if ( i >= current_month )
cout << "(Previous year)";
cout << "\naverage\t ";
bargraph( rainfall[i].avg_rain_fall );
cout << "\nactual\t ";
bargraph( rainfall[i].rain_fall );
cout << endl;

if ( 5 == i )
{
output_scale();
}
}
output_scale();
}

The rainfall averages in the data come from The World Almanac and Book of Facts 1993,
published by the World Almanac. (C) Phaos Books,1992. The rainfall numbers presented
here are made-up.

This is the 'data file' used to test this program:

$cat data
3.7 3.6 5.1 3.8 4.2 4.2 4.4 4.8 4.0 3.3 3.3 3.5
4
4.3 3.2 5.5 5.1 4.0 2.2 2.0 1.1 4.1 3.3 3.9 3.7
t
y
3.7 3.6 5.1 3.8 4.2 4.2 4.4 4.8 4.0 3.3 3.3 3.5

14
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

4
4.3 3.2 5.5 5.1 4.0 2.2 2.0 1.1 4.1 3.3 3.9 3.7
g
y
3.7 3.6 5.1 3.8 4.2 4.2 4.4 4.8 4.0 3.3 3.3 3.5
4
4.3 3.2 5.5 5.1 4.0 2.2 2.0 1.1 4.1 3.3 3.9 3.7
h
n

The command used to run the program and the output is:
17:19:43:~/AW$ a.out < data > ch7prb2.out

There follows edited output obtained from this run. I have 'redacted' the input and the
output where either is identical for all three runs and after it has been seen.

$cat ch7prb2.out
Monthly rainfall input routine.

Please enter the average rainfall for each month


Average rainfall:
For month January Avg Rainfall: 3.7
For month February Avg Rainfall: 3.6
For month March Avg Rainfall: 5.1
For month April Avg Rainfall: 3.8
For month May Avg Rainfall: 4.2
For month June Avg Rainfall: 4.2
For month July Avg Rainfall: 4.4
For month August Avg Rainfall: 4.8
For month September Avg Rainfall: 4
For month October Avg Rainfall: 3.3
For month November Avg Rainfall: 3.3
For month December Avg Rainfall: 3.5

The actual rainfall:

15
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

What is the current month? Please give the number of the month (Jan = 0,
etc.
The current month is: May
Please enter the actual rainfall for each month, as prompted, First for
the
months in the previous year:
For month May Rainfall: 4.3
For month June Rainfall: 3.2
For month July Rainfall: 5.5
For month August Rainfall: 5.1
For month September Rainfall: 4
For month October Rainfall: 2.2
For month November Rainfall: 2
For month December Rainfall: 1.1
Now for the months in this year:
For month January Rainfall: 4.1
For month February Rainfall: 3.3
For month March Rainfall: 3.9
For month April Rainfall: 3.7
Please choose between g)raphical and t)abular output
You chose the tabular output.
Monthly Rainfall
For the 12 Months Preceding May
Actual, Average, and Difference (= Actual - Average)
-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
average 4.1 | 3.3 | 3.9 | 3.7 | 4.3 | 3.2 | 5.5 | 5.1 | 4.0 | 2.2 | 2.0 | 1.1
actual 3.7 | 3.6 | 5.1 | 3.8 | 4.2 | 4.2 | 4.4 | 4.8 | 4.0 | 3.3 | 3.3 | 3.5
diffs 0.4 |-0.3 |-1.2 |-0.1 | 0.1 |-1.0 | 1.1 | 0.3 | 0.0 |-1.1 |-1.3 |-2.4
P)rev yr | | | | P | P | P | P | P | P | P | P

Y/y continues, any thing else quits


Monthly rainfall input routine.

Please enter the average rainfall for each month

16
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Average rainfall:
For month January Avg Rainfall: 3.7
. . . .
For month December Avg Rainfall: 3.5

The actual rainfall:


What is the current month? Please give the number of the month (Jan = 0, etc.
The current month is: May
Please enter the actual rainfall for each month, as prompted, First for the
months in the previous year:
For month May Rainfall: 4.3
. . . .
For month December Rainfall: 1.1
Now for the months in this year:
For month January Rainfall: 4.1
. . . .
For month April Rainfall: 3.7
Please choose between g)raphical and t)abular output
You chose the graphical output

Rainfall 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
|****|****|****|****|****|****|****|****|****|****|****|****|****|****
January
average **************************************
actual *****************************************
February
average *************************************
actual *********************************
March
average ***************************************************
actual ***************************************
April
average **************************************
actual **************************************
May (Previous year)
average *******************************************

17
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

actual *******************************************
June (Previous year)
average *******************************************
actual *********************************

Rainfall 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
|****|****|****|****|****|****|****|****|****|****|****|****|****|****
July (Previous year)
average *********************************************
actual *******************************************************
August (Previous year)
average ************************************************
actual ***************************************************
September(Previous year)
average ****************************************
actual ****************************************
October (Previous year)
average *********************************
actual ***********************
November(Previous year)
average *********************************
actual ********************
December(Previous year)
average ***********************************
actual ************

Rainfall 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
|****|****|****|****|****|****|****|****|****|****|****|****|****|****
Y/y continues, any thing else quits
Monthly rainfall input routine.

Please enter the average rainfall for each month


Average rainfall:
For month January Avg Rainfall: 3.7

. . . .

18
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

For month December Avg Rainfall: 3.5

The actual rainfall:


What is the current month? Please give the number of the month (Jan = 0, etc.
The current month is: May
Please enter the actual rainfall for each month, as prompted, First for the
months in the previous year:
For month May Rainfall: 4.3

. . . .

For month December Rainfall: 1.1


Now for the months in this year:
For month January Rainfall: 4.1
. . . .
For month April Rainfall: 3.7
Please choose between g)raphical and t)abular output
You typed neither of the choices. Defaulting to graphical output.

Rainfall 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
|****|****|****|****|****|****|****|****|****|****|****|****|****|****
January
average **************************************
actual *****************************************

. . . .

April
average **************************************
actual **************************************
May (Previous year)
average *******************************************
actual *******************************************

. . . .

19
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

December(Previous year)
average ***********************************
actual ************

Rainfall 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
|****|****|****|****|****|****|****|****|****|****|****|****|****|****
Y/y continues, any thing else quits

Notes On transforming this into a structure free program.

Much of the program with structs will be identical to the version without. This makes
transforming one into the other easy. This is particularly true when we are moving from
using structs to not using structs.

First, declare local variables in main:

int month;
double rain_fall[12];
double avg_rain_fall[12];

Pass these to each function called from main, and modify each function to access these
rather than the structure, for example, the input routine would have declaration:

void input ( double rain_fall[], double avg_rain_fall[],


int current_month );

and the two output routines would have the same sort of declaration:

void output_bargraph ( double rain_fall[],


double avg_rain_fall[],
int current_month );
void output_table ( double rain_fall[],
double avg_rain_fall[],

20
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

int current_month );

The changes necessary internal to the routines is illustrated here. We replace this following
loop from the input routine,

for ( i = current_month; i < 12; i++)


{
cout << "For month ";
full_month_name(i);
cout << " ";
cin >> rainfall[i].rain_fall;
cout << "\tRainfall: " << rainfall[i].rain_fall;
cout << endl;
}

with this:

for ( i = current_month; i < 12; i++)


{
cout << "For month ";
full_month_name(i);
cout << " ";
cin >> rain_fall[i];
cout << "\tRainfall: " << rain_fall[i];
cout << endl;
}

These changes will produce the required struct free solution.

Programming Project 2: Hexadecimal Addition


Problem statement and my commentary are in comments in the following source.

// This program is to accept two hexadecimal numbers, to be stored as


// arrays of up to 10 characters. The program should add these numbers.

21
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//
// If the sum can be contained in 10 digits, output the sum
// otherwise output an indication of overflow error.
//
// Provide a loop to repeat the action until user wants to end program.
//
// Note on overflow detection. Overflow occurs when the carry bits into
// and out of the highest digit are both set. This condition is is
// equivalent to the text's "when the result will not fit in 10
hexadecimal
// digits", and is easy to test.
//
// My solution requires that the Hex digits A-F be entered upper case.
// A nice enhancement would be to allow either case.
//
// Finally, debugging this was a bear. I have left a some of my test
// code (but by no means all) for (what I hope will be) the student's
// edification.
//
// Be certain that the student tests the program with single digit, two
// digit and with all numbers of data all the way to 10 hex digits, in
all
// combinations in each of the two input positions, and test with short
// data before and after many digit data and conversely.
//

#include <iostream>

void input(char num[])


{
using std::cout;
using std::cin;
using std::endl;

cout << "Enter a hexadecimal number of 10 or fewer hex digits\n"


<< "Hex digits are 0-9A-F Code requires uppercase A through F\n"
<< "Press lower case q to stop entry of the hex digits\n";

int i = 0;
char c = '0';
while(c != 'q')
{
cin >> c;
num[i] = c;
i++;
}
num[--i] = '0';

// cout << " i " << i << endl;

// cout << "num[" << i << "] is " << num[i] << endl << endl;
// i is the of the last number entered
// reverse segment [0, i), that is 0<= k < i
// to put the least significant digit in the

22
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// index 0 position.

char tmp;
for(int k = 0; k < i/2; k++)
{
tmp = num[k];
num[k] = num[i-1-k ];
num[i-1-k]=tmp;
}
}

// internal to the program, hex numbers are stored


// with least significant digit first we output
// most significant to least significant
void output(char num[])
{
using std::cout;

for(int i = 9; i >=0; i--)


cout << num[i];
}

void hexSum(char num1[], char num2[], char sum[])


{
using std::cout;
using std::endl;

int x, y, s, carry = 0, nextCarry = 0;

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


{
if('0' <= num1[i] && num1[i] < '0' + 10)
{
// cout << "decimal digit" << endl;
x = num1[i] - '0';
}
else
{
// cout<< "hex digit\n";
x = num1[i] - 'A' + 10;
// cout << "value of num1[" << i << "] is " << x << endl;
}

if('0' <=num2[i] && num2[i] < '0'+ 10)


{
// cout << "num2 is digit 0-9" << endl;
y = num2[i] - '0';
// cout << "value of num2[" << i << "] is " << x << endl;
}
else
{
// cout<< "hex digit" << nuum2[i] << endl;

23
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

y = num2[i] - 'A' + 10;


// cout << "value of num2[" << i << "] is " << x << endl;

carry = nextCarry;
s = (x + y + carry)%16; // digit value
// cout << "s " << s << endl;

nextCarry = (x + y + carry)/16; // nextCarry is carry for next digit

// cout << "carry " << carry << endl;


//convert back to hex.
if(0 <= s && s < 10)
{
sum[i] = char('0' + s);
}
else if(10 <= s && s < 16)
sum[i] = char('A' + s - 10);
else
{
cout <<"bad values " ;
}
// cout << sum[i] << endl;
}
// cout << endl;
if(1 == carry && 1 == nextCarry)
cout << "\n\n*********Overflow Error ***********\n\n";
}

int main()
{
using std::cout;
using std::cin;
using std::endl;

char ans = 'y';


while (ans == 'y')
{
// put definitions and initialization here so each time through
// variables get initialized.
char num1[10] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
char num2[10] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
char sum[10] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
char temp[10] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};

input(num1);
cout << endl;
output(num1);
cout << endl;
input(num2);
cout << endl;
output(num2);

24
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << endl << endl;

hexSum(num1, num2, sum);

cout << " "; // for alignment


output(num1);
cout << " \n";
cout << "+";
output(num2);
cout << "\n------------\n "; // space at end for alignment
output(sum);

cout << endl;


cout << "y continues\n\n";
cin >> ans;
}

return 0;
}

/*

Typical run using the data in data7.2.txt:

FEDCBA9876q
123456789Aq
y
CEDCBA9876q
123456789Aq
y
DEDCBA9876q
123456789Aq
n

The first line here is the command line to execute this


program with the data specified.

ch7.2.exe < data7.2.txt


Enter a hexadecimal number of 10 or fewer hex digits
Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

FEDCBA9876
Enter a hexadecimal number of 10 or fewer hex digits
Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

123456789A

*********Overflow Error ***********

25
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

FEDCBA9876
+123456789A
------------
1111111110
y continues

Enter a hexadecimal number of 10 or fewer hex digits


Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

CEDCBA9876
Enter a hexadecimal number of 10 or fewer hex digits
Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

123456789A

CEDCBA9876
+123456789A
------------
E111111110
y continues

Enter a hexadecimal number of 10 or fewer hex digits


Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

DEDCBA9876
Enter a hexadecimal number of 10 or fewer hex digits
Hex digits are 0-9A-F Code requires uppercase A through F
Press lower case q to stop entry of the hex digits

123456789A

DEDCBA9876
+123456789A
------------
F111111110
y continues

*/

Programming Project 3. Delete Repeats


//Problem: to write (and test) a function that has a
//partially filled array of characters as a formal parameter.
//A partially filled array requires two parameters, the array
//itself and a size parameter. The function deletes all
//repeated letters from the array, and close up the 'empty'

26
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//positions, then decrease the size parameter.


//Test this function.

//The main program generates test data.

#include <iostream>

//modifies ‘array’ to delete all instances of any duplicates


//of characters found in ‘array’
void delete_duplicates( char array[], int& size );

//returns number of characters up to the null terminator, \0


int length( char array[]);

int main()
{
using namespace std;
char array[81]
= "mary had a little lamb. its fleece was white as snow.";
cout << array << endl;
int size;
size = length(array);
cout << "size = " << size << endl;

delete_duplicates( array, size);

cout << "reduced array = " << array << endl;


cout << "reduced array size = " << size << endl;

char array1[81]
="Now is the time for all good men to come to the aid of the country.";

cout << array1 << endl;


size = length(array1);
cout << "size = " << size << endl;

27
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

delete_duplicates( array1, size);

cout << "reduced array = " << array1 << endl;


cout << "reduced array size = " << size << endl;
}

void delete_duplicates( char array[], int& size )


{
for ( int i = 0; i < size ; i++)
{
for ( int j = i+1; j < size; j++ )
if ( array[j] == array[i] )
{
//close up array, overwriting array[j]
for ( int k = j; k < size; k++)
array[k] = array[k+1];
j--; //backup, look at this character again!
size--;
}
}
}

int length( char array[])


{
for ( int i=0; '\0' != array[i]; i++) //strings are terminated by a \0
{ //length is the position of '\0'
//body deliberately empty
}
return i;
}

A test run:
22:24:31:~/AW$ a.out
mary had a little lamb. its fleece was white as snow.
size = 53
reduced array = mary hdliteb.sfwno

28
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

reduced array size = 18


Now is the time for all good men to come to the aid of the country.
size = 67
reduced array = Now isthemfralgdncuy.
reduced array size = 21

I found it interesting to do this by hand and compare to the program output.

Programming Project 4: Standard Deviation

// Define a function that takes a partially filled array of doubles


// as one of two arguments (the other is the size), and returns the
// standard deviation of the numbers in the partially filled array.
// Embed in a program and test.

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

const int MAX_SIZE = 10;

// Pre: size <= declared size of the array argument


// Post: return the standard deviation first size array elements
// Note: The divisor is the size, not size - 1 as some
// formuals call for.
double stdDev(double s[], int size);

// Pre: size <= declared size of the array argument


// Post: return the mean of the first size array elements
double average(double s[], int size);

int main()
{
double s[MAX_SIZE];
double stdDeviation, avg;

29
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

char ans;
do
{
cout << "Enter " << MAX_SIZE << " values, separated by\n"
<< " white space, Terminated each with <cr>. \n"
<< "I will compute the standard deviation.\n";

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


cin >> s[i];

stdDeviation = stdDev(s, MAX_SIZE);

cout << "The Standard Deviation is: "


<< stdDeviation << endl;
cout << "Y/y continues, any other quits.\n";
cin >> ans;
} while(ans == 'y' || ans == 'Y');

return 0;
}

double stdDev(double s[], int size)


{
double sumSquares = 0;
double avg = average(s, size);

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


sumSquares += (s[i] - avg) * (s[i] - avg);

return sqrt(sumSquares / size);


}

double average(double s[], int size)


{
double sum = 0;

30
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

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


sum += s[i];

return sum / size;


}

Programming Project 7: A Long integer Adder

I emphasize strongly that divide and conquer is the secret to successful programming,
regardless of the paradigm. This is why object oriented programming, object based
programming, and procedure oriented programming are effective. Each of these techniques
has its collection of problems for which that particular technique works best. The idea that
is common to these techniques on is the encapsulation of commonalties, the separation of
issues, and the hiding of detail.

//Purpose: to sum two large integers (up to 20 digits each).


//
//Input: digits of two integers
//It appears that a "partially filled array structure" is of
//use here.
//
//Output: the sum of the two large integers is written to the
//screen
//
//algorithm: computer version of the traditional paper and pencil
//algorithm.

//Add low order digits, record carry


//while digits remain,
// add next higher order digits and the carry, recording
// the carry

31
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//If the sum is beyond the capacity of a 20 digit array to


//represent, the program is to report overflow.

#include <iostream>
#include <cstdlib>
#include <cctype>

const int MAX_DIGITS = 20;

struct Large_integer //Design decision: lower indices


correspond
{ //to lower order digits
int digit[MAX_DIGITS+1]; //Making room for the null terminator.
int size; //number of digits
};

//fetches a sequence of digits from the input,


//converts to integer values, records size
void input( Large_integer& number );

//displays the Large_integer's digits in correct order


//on the screen
void output( Large_integer number );

//input: two large integers


//output: a large integer that is the sum of the inputs
void add ( Large_integer first, Large_integer second,
Large_integer& sum);

32
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

int main()
{
using namespace std;
Large_integer first, second, sum;
cout << "Large integer summing program " << endl;
cout << "Please enter an integer, 20 digits or less "
<< endl;
input( first );
cout << "you entered " << endl;
output (first);
cout << endl;
cout << "Enter another integer, 20 digits or less" << endl;
input( second );
cout << "you entered " << endl;
output (second); cout << endl << endl;

cout << "The sum is: " << endl;


output(first);
cout << endl;
output(second);
cout << endl;
cout << "----------------------" << endl;
add (first, second, sum );
output( sum );
cout << endl;

33
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void input( Large_integer& number )


{
using namespace std;
char ch;
int i = 0;
number.size = 0;
cin.get(ch);
while( '\n' != ch ) //This error handling is too drastic.
{ //Error handling should allow user to
//reenter the number.
if ( !isdigit(ch) )
{
cout << "non digit entered. Aborting. " << endl;
exit(1);
}
number.digit[i] = ch - '0'; //chars are automatically
number.size++; //promoted to integers.
i++;
cin.get(ch);
}

//more draconian error control!


if (number.size > 20 )
{
cout << "Input number size too large. Aborting." <<endl;
exit(1);
}

//Reverse array

34
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

for ( int k = 0; k < number.size/2; k++ )


{
int temp = number.digit[k];
number.digit[ k ] = number.digit[ number.size - 1 - k ];
number.digit[ number.size - 1 - k ] = temp;
}
}

void output( Large_integer number )


{
using namespace std;
//lead spaces to visually align the output.
for ( int i = 20; i >= number.size; i--)
cout << " ";
for ( i = number.size - 1; i >= 0; i-- )
cout << number.digit[i];
}

void add ( Large_integer first,


Large_integer second, Large_integer& sum)
{
int carry = 0;
int larger_size;
//pad the input with the smaller number of digits to the
//size of the larger with zeros.
if ( first.size > second.size )
{
for( int i = second.size; i < first.size; i++)
second.digit[i] = 0;

35
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

larger_size = first.size;
}
else
{
for( int i = first.size; i < second.size; i++)
first.digit[i] = 0;
larger_size = second.size;
}

//code to do the addition ...


for ( int i = 0; i < larger_size; i++)
{
sum.digit[i] = first.digit[i] + second.digit[i] + carry;
if (sum.digit[i] > 9 )
{
carry = 1;
sum.digit[i] = sum.digit[i] - 10;
}
else
carry = 0;
}
if ( 1 == carry )
{
if( larger_size == 20) //the carry is out of digit 20
{
cout << "An overflow has occurred. "
<< "Result is set to 0" << endl;
sum.size = 1;
sum.digit[0] = 0;

36
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

}
else //the result is legal.
{
sum.digit[larger_size] = carry;
sum.size = larger_size + 1;
}
}
else //no carry, no problem
sum.size = larger_size;
}

A typical run follows:

$:~/AW$ a.out
Large integer summing program
Please enter an integer, 20 digits or less
2345676543456312987
you entered
2345676543456312987
Enter another integer, 20 digits or less
432256456785678689
you entered
432256456785678689

The sum is:


2345676543456312987
432256456785678689
----------------------
2777933000241991676
15:28:11:~/AW$

37
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Some of the error checking is tested here:

15:28:49:~/AW$ a.out
Large integer summing program
Please enter an integer, 20 digits or less
9898987656545434334445546
Input number size too large. Aborting.
15:28:57:~/AW$

If the input number is too long, the program aborts:

15:29:22:~/AW$ a.out
Large integer summing program
Please enter an integer, 20 digits or less
98765432101234567890
you entered
98765432101234567890
Enter another integer, 20 digits or less
234567890987654321123
Input number size too large. Aborting.

Finally, the overflow error test:

15:31:49:~/AW$a.out
Large integer summing program
Please enter an integer, 20 digits or less
98765432109876543210
you entered

38
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

98765432109876543210
Enter another integer, 20 digits or less
56789012345678901234
you entered
56789012345678901234

The sum is:


98765432109876543210
56789012345678901234
----------------------
An overflow has occurred. Result is set to 0
0

Programming Project 7b: Adder without structures.

It took about 15 minutes to convert from the struct solution to this non-struct solution. A
reason why the conversion is easy is the structure (pun intended) imposed on the
programming by the use of the struct to relay the information to and from the functions.
Going the other direction is harder.

I changed the functions declarations (prototypes) to eliminate the struct, then I changed the
main program to agree with the function declarations (prototypes). Then the code in the
input, output, and add functions had to be changed. This amounted to doing a query-replace
of .digit by the empty string, and replacing first.size, second.size, sum.size, number.size
with the . replaced by an underscore.

The result compiles and runs with exactly the same user interface.

Here is the result:

//The Adder problem without structures.


//Purpose: to sum two large integers (up to 20 digits each).

39
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//
//Input: digits of two integers
// It appears that a "partially filled array structure"
//from the text will be of value here.
//Output: the sum of the two large integers is written to the
//screen
//
//algorithm: computer version of the traditional paper and
// pencil algorithm.

//add low order digits, record carry.


//while digits remain,
// add next higher order digits and the carry, recording
// the carry
//If the sum is beyond the capacity of a 20 digit array to
//represent, the program, then report overflow.

#include <iostream>
#include <cstdlib>
#include <cctype>

const int MAX_DIGITS = 20;

//fetches a sequence of digits from the input,


//converts to integer values, records size
void input( int number[], int& size);

//displays the Large_integer's digits in correct order


//on the screen

40
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void output( const int number[], int size);

//input: two large integers


//output: a large integer that is the sum of the inputs
void add ( int first[], int first_size, int second[],
int second_size, int sum[], int& sum_size);

int main()
{
//Design decision: lower indices correspond
//to lower order digits
using namespace std;
int first[MAX_DIGITS+1];
int first_size; //number of digits first_sizE
int second[MAX_DIGITS +1];
int second_size;
int sum[MAX_DIGITS +1];
int sum_size;

cout << "Large integer summing program " << endl;


cout << "Please enter an integer, 20 digits or less "
<< endl;
input( first, first_size );
cout << "you entered " << endl;
output (first, first_size);
cout << endl;
cout << "Enter another integer, 20 digits or less" << endl;
input( second, second_size );
cout << "you entered " << endl;

41
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

output (second, second_size); cout << endl << endl;

cout << "The sum is: " << endl;


output(first, first_size);
cout << endl;
output(second, second_size);
cout << endl;
cout << "----------------------" << endl;
add(first, first_size, second,
second_size, sum, sum_size );
output( sum, sum_size );
cout << endl;
}

void input( int number[], int& number_size )


{
using namespace std;
char ch;
int i = 0;
number_size = 0;
cin.get(ch);
while( '\n' != ch ) //This error handling is too drastic.
{ //Error handling should allow user to reenter the number.
if ( !isdigit(ch) )
{
cout << "non digit entered. Aborting. " << endl;
exit(1);
}
number[i] = int(ch) - int('0');

42
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

number_size++;
i++;
cin.get(ch);
}

//more draconian error control!


if (number_size > 20 )
{
cout << "Input number size too large. Aborting." <<endl;
exit(1);
}

//Reverse array
for ( int k = 0; k < number_size/2; k++ )
{
int temp = number[k];
number[ k ] = number[ number_size - 1 - k ];
number[ number_size - 1 - k ] = temp;
}
}

void output( const int number[], int number_size )


{
using namespace std;
//lead spaces to visually align the output.
for ( int i = 20; i >= number_size; i--)
cout << " ";
for ( i = number_size - 1; i >= 0; i-- )
cout << number[i];

43
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void add ( int first[], int first_size,


int second[], int second_size,
int sum[], int& sum_size)
{
using namespace std;
int carry = 0;
int larger_size;
//pad the input with the smaller number of digits to the
//size of the larger with zeros.
if ( first_size > second_size )
{
for( int i = second_size; i < first_size; i++)
second[i] = 0;
larger_size = first_size;
}
else
{
for( int i = first_size; i < second_size; i++)
first[i] = 0;
larger_size = second_size;
}

//code to do the addition ...


for ( int i = 0; i < larger_size; i++)
{
sum[i] = first[i] + second[i] + carry;
if (sum[i] > 9 )

44
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
carry = 1;
sum[i] = sum[i] - 10;
}
else
carry = 0;
}
if ( 1 == carry )
{
if( larger_size == 20) //the carry is out of digit 20
{
cout << "An overflow has occurred. "
<< "Result is set to 0" << endl;
sum_size = 1;
sum[0] = 0;
}
else //the result is legal.
{
sum[larger_size] = carry;
sum_size = larger_size + 1;
}
}
else //no carry, no problem
sum_size = larger_size;
}

Programming Project 8: Letter Frequency

A note on programming principles recalled while doing this problem:

45
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Students should NOT ATTEMPT to do TOO MUCH in any one function! This leads to
code that is impossible to understand, even for the author of the code. There will be no end
of trouble debugging such code.

The principle of cohesiveness of a module (whether the module is a function, a class or a


file of functions) states that a module should do one task or a collection of closely related
tasks. A programmer violates this rule at considerable peril.

Urge the students to get one function running first. I usually try to get main running with
stubs, but debugging functions with drivers helps. Then the student should try to get the
whole program running by adding functions to the main one at a time.

This pays off when the programmer discovers that a design error has been made. The
principle of doing a small number of connected things in a function tends to confine the
necessary repairs to one or at most a very few modules, functions, or class member
functions.

//8. Letter Frequency


//
//Input: a line of text terminated with a period, which serves as
//sentinel.
//Output: a list of letters sorted into decreasing order by
//frequency.
//
//Data Structure: array of struct, struct holds a char and int
//(the count).
//
//Algorithm:
//The text is scanned a character at a time, if the character
//is present in the data structure, then update the count, if
//not present insert the new character in the data structure,

46
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//update the count to 1. The array of structs is sorted on


//the count key.

#include <iostream>
#include <cassert>
#include <cctype>

struct char_freq
{
char ch;
int count;
};

//NOTE that all that is necessary in the headers is to


//replace int with char_freq

void sort(char_freq a[], int number_used);


//Precondition: number_used <= declared size of the array a.
//The array elements a[0] through a[number_used - 1] have
//values.
//Postcondition: The values of a[0] through
//a[number_used - 1] have been rearranged so that
//a[0] <= a[1] <= ... <= a[number_used - 1].

void swap_values(char_freq& v1, char_freq& v2);


//Interchanges the values of v1 and v2.

int index_of_smallest(const char_freq a[],


int start_index, int number_used);

47
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//Precondition: 0 <= start_index < number_used.


//Referenced array elements have values.
//Returns the index i such that a[i].count is the smallest of
//the values
//a[start_index].count, a[start_index + 1].count, ...,
//a[number_used - 1].count

void input( char_freq list[], int& size);


//list is an array of char_freq structs.
//reads input, period is sentinel. Sets the char members of the
//char_freq struct elements of list to newly occurring characters,
// otherwise, if the struct already has the character, this routine
// increments the count for that character.

void output( char_freq list[], int size );


//lists Letter, Number of Occurrences in columns

int main()
{
char_freq list[50] ={0,0}; //we are going to pick up
//punctuation, etc.
int list_size = 0;
input( list, list_size );
sort( list, list_size );
output( list, list_size);
return 0;
}

//traverses the elements of list through size elements

48
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//if an element containing c is found,


// increment count in the list member for that character
// returns true (1) (c is in the list)
//else
// returns false(0) (c is not in the list)
bool lookup( char c, char_freq list[], int& size );

//precondition: c is not in the list


//post condition: c has been added in position size,
//size has been incremented.
//size <= 26
void insert( char c, char_freq list[], int& size );

void input(char_freq list[], int& size)


{
using namespace std;
char ch;
cin >> ch; //we want to ignore blanks, so we use cin >>...
ch = tolower(ch); // Push everything to lowercase.
while('.' != ch)
{
if (!lookup(ch, list, size))
insert(ch, list, size);
cin >> ch;
}
}

void insert(char c, char_freq list[], int& size)


{

49
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

list[size].count=1;
list[size].ch = c;
size ++;
assert( size <= 26);
}

bool lookup(char c, char_freq list[], int& size)


{
int i = 0;
bool success = false;
do
{
if (c == list[i].ch)
{
list[i].count++;
success = true;
return success;
}
i++;
} while(i <= size);
assert(i <= 27); //Debugging aid, see the Text’sAppendix
//for the details of the Assert macro.
return success;
}

void output( char_freq list[], int size )


{
using namespace std;

50
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << "Letter:\tNumber of Occurrences." << endl;


for ( int i = 0; i < size; i++)
cout << list[i].ch << '\t' << list[i].count << endl;
}

A data file

21:55:53:~/AW$ cat file1


Now is the time for all good men to come to the aid of the
country for if they do not, the whole thing may break up and
go down the drain.
21:55:56:~/AW$

Output generated before sorting.

21:55:10:~/AW$ a.out < file1


Letter: Number of Occurrences.
n 8
o 15
w 3
i 6
s 1
t 12
h 8
e 11
m 4
f 4
r 5
a 6
l 3
g 3

51
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

d 6
c 2
u 2
y 3
, 1
b 1
k 1
p 1
21:55:15:~/AW$

Here is some output after the sort routine was modified for use here. See that file for some
suggestions on how to modify it.

23:44:52:~/AW$ a.out
Mary had a little lamb Its fleece was white as snow.
Letter: Number of Occurrences.
a 6
e 5
s 5
l 4
t 4
w 3
i 2
h 2
m 2
y 1
b 1
I 1
r 1
f 1
d 1

52
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

n 1
o 1

Programming Project 9: Poker Hand Evaluator

// Score a five-card poker hand into one of the following


// categories:
// nothing
// one pair
// two pairs
// three of a kind
// straight (in order, no gaps)
// flush ( all same suite, for example, all spades)
// full house (one pair and three of a kind)
// four of a kind
// straight flush (hand is both a straight and flush)

//Use array of struct to store the hand. Structure will have


//two member variables: one for the value of the card and one
//for the suit.

//Include a loop that allows the user to continue to score more


//hands until the user says the program should end.

//Programming note:
//I made a design error that I did not discover until the program
//was in final testing. Because the problem had been written using
//the principle "one function does one thing", the changes needed
//were confined to just a few functions.

53
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//
//I had used a char for the face value, using 2 - 9 and the 't'
//'j' 'q' 'k' and 'a' for ten through ace. For test data that was
//a digit, the sort routine for the struct from an earlier problem
//(modified to sort small to large) worked fine. Once a test was
//made using any of the "face cards" ten, jack, queen, king, ace.
//It was found that the sort routine worked. BUT NOT correctly.

//In this problem, ten < jack < queen < king < ace. BUT the
//order using the ASCII encoding is 'a' < 'k' < 'q' < 't'
//which is not at all what we need. The use of the enum for the
//face value of the card with the few changes this necessitated
//was the necessary repair. This should be no problem for the
//student, since the enum is dealt with in the text with
//considerable care in Chapter 3, page 354 and following.

//If you have not done the enum data type, I have presented, but
//have commented out, declarations that can be used to side step
//this problem, and have added (also commented out) const int
//declarations for the enum constants along with suggestions for
//replacing the three enum tags with int.

//Compile command: (Use the appropriate command for your


//system – BCC32, CL –GX, CC etc.)
//g++ ch7prg8.cpp sort_hand.cpp

#include <iostream>
#include <cstdlib>
#include <cctype>

54
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

enum Hand_Value { NOTHING, ONE_PAIR, TWO_PAIRS, THREE_OF_KIND,


STRAIGHT, FLUSH,FULL_HOUSE, FOUR_OF_KIND,
STRAIGHT_FLUSH};

//Remark: It is recommended that enum constants be upper case.


//I violated this with the word flush, and got the very unclear
//error message: '5' redeclared as different kind of symbol.
//The error occurs because flush is already declared in the
//iostream library.

enum Card_Suite { CLUBS, DIAMONDS, HEARTS, SPADES };


enum Face_Value { TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
NINE, TEN, JACK, QUEEN, KING, ACE };

//If you have not done enums, the following declarations enable
//this code to run correctly without the enum declarations. You
//may wish to do a global search and replace instead of using
//these typedef statements, since typedef has not yet been
//treated in the text. There is a short discussion of typedef
//in the text. See the box, Type Definitions.
//typedef int Card_suite;
//typedef int Face_Value;
//typedef int Hand_Value;
//const int NOTHING =0 , ONE_PAIR= 1, TWO_PAIRS=3,
// THREE_OF_KIND=4, STRAIGHT=5, FLUSH=6,FULL_HOUSE=7,
// FOUR_OF_KIND=8, STRAIGHT_FLUSH=9;
//const int CLUBS=0, DIAMONDS=1, HEARTS=2, SPADES=3;
//const int TWO=0 , THREE=1, FOUR=2, FIVE=3, SIX=4, SEVEN=5,

55
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// EIGHT=6, NINE=7, TEN=8, JACK=9, QUEEN=10, KING=11,


// ACE=12;
//
//I tested these changes.

// Consideration: Re-write this using enum classes, which


// would avoid the “Flush” problem!

struct Card
{
Card_Suite suite;
Face_Value face;
};

//this will be in main


//Card hand[5];

//Helping function for input routine


//This greatly simplifies the work in the rest of the program.
//Postcondition: The Card hand[] array is sorted on value
//The student should modify sort from the previous problem.
void sort_hand ( Card hand[], int number_used );

//Prompts for and fetches a hand from standard input


void input ( Card hand[] );

//Helping functions for evaluate( Card hand[] );

int has_four(Card hand[]);

56
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//Precondition: function is called


//Postcondition:
//if there are 4 equal values in the hand,
// returns true
//else
// returns false

int has_three (Card hand[]);


//Precondition: has_four returns false when called on this hand
//Postcondition:
//if there are 3 of a kind,
// returns true,
//else
// returns false

int is_full_house ( Card hand[] );


//Postcondition:
//if the two cards other than the three of a kind are equal,
// return true
//else
// return false

int has_two_pair( Card hand[]);


//precondition: has_four returns false.
//if two pair are in the hand, returns true
//else returns false

int has_one_pair( Card hand[]);

57
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//Precondition: has_four, has_three, has_two_pair all return


//false if one pair are in the hand, returns true else returns
//false

int is_straight (Card hand[]);


//Precondition: function has been called
//Postcondition:
//if the cards are in sequence,
// return true
//else
// return false

int is_flush( Card hand[] );


//Precondition: function is called
//Postcondition:
//if all cards have same suite,
// return true
//else
// return false

Hand_Value evaluate(Card hand[]);


//Precondition: function is called with a poker hand array of
// Cards
//Postcondition: hand is evaluated and an appropriate value
//from enum Hand_Value is returned

//lists hand in format suite, value


void output_hand( Card hand[] );

58
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//calls evaluate then outputs translation of enum Hand_Value


void report_hand_value( Card hand[]);

//reports hand in human readable form


void output_hand( Card hand[] );

int main()
{
using namespace std;
char ans;
Card hand[5];
cout << "Poker Hand Evaluation Program - " << endl
<< "Please Enter a 5 card poker hand, "
<<"I'll evaluate this "
<< "hand as one of " << endl
<< "NOTHING, ONE_PAIR, TWO_PAIRS, THREE_OF_KIND, "
<< "STRAIGHT FLUSH, FULL_HOUSE" << endl
<< "FOUR_OF_KIND, or STRAIGHT_FLUSH" << endl << endl
<< "Encode Clubs as c, Diamonds as d, Hearts as h, "
<< " Spades as s" << endl
<< "Enter the value as 2-9, t, j, q, k a, "
<< " Upper case OK " << endl << endl;
do
{
input ( hand );
cout << "\nSorted hand is: " << endl;
output_hand( hand );
cout << "value of hand is: " ;
report_hand_value( hand );

59
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << endl << endl;


cout << "Y/y continues, other halts." << endl << endl;
cin >> ans;
}while ( 'Y' == ans || 'y' == ans );
}

void report_hand_value( Card hand[])


{
switch( evaluate( hand ) )
{
case NOTHING:
cout << "Nothing";
break;
case ONE_PAIR:
cout << "One Pair";
break;
case TWO_PAIRS:
cout << "Two Pair";
break;
case THREE_OF_KIND:
cout << "Three of a Kind";
break;
case STRAIGHT:
cout << "Straight";
break;
case FLUSH:
cout << "Flush";
break;
case FULL_HOUSE:

60
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << "Full House";


break;
case FOUR_OF_KIND:
cout << "Four of a Kind";
break;
case STRAIGHT_FLUSH:
cout << "Straight Flush";
break;
default:
cout << " Something is very wrong. Bad value ";
break;
}
}

Hand_Value evaluate( Card hand[] )


{
Hand_Value value;
if ( is_straight(hand) )
if (is_flush( hand ))
return STRAIGHT_FLUSH;
if ( has_four(hand) )
return FOUR_OF_KIND;
if (is_full_house(hand) )
return FULL_HOUSE;
if (is_flush(hand) )
return FLUSH;
if (is_straight(hand) )
return STRAIGHT;
if ( has_three(hand) )

61
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

return THREE_OF_KIND;
else if ( has_two_pair(hand) )
return TWO_PAIRS;
else if ( has_one_pair(hand) )
return ONE_PAIR;
else return NOTHING;
}

void get_face ( Face_Value & value)


{
using namespace std;
char ch;
cin >> ch;
switch( ch )
{
case '2': value = TWO;
break;
case '3': value = THREE;
break;
case '4': value = FOUR;
break;
case '5': value = FIVE;
break;
case '6': value = SIX;
break;
case '7': value = SEVEN;
break;
case '8': value = EIGHT;
break;

62
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

case '9': value = NINE;


break;
case 't': value = TEN;
break;
case 'j': value = JACK;
break;
case 'q': value = QUEEN;
break;
case 'k': value = KING;
break;
case 'a': value = ACE;
break;
default: cout << "Bad face value. Aborting!";
exit(1);
}
}

void put_face ( Face_Value& face)


{
using namespace std;
switch ( face )
{
case TWO: cout << 2;
break;
case THREE: cout << 3;
break;
case FOUR: cout << 4;
break;
case FIVE: cout << 5;

63
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

break;
case SIX: cout << 6;
break;
case SEVEN: cout << 7;
break;
case EIGHT: cout << 8;
break;
case NINE: cout << 9;
break;
case TEN: cout << 10;
break;
case JACK: cout << "Jack";
break;
case QUEEN: cout << "Queen";
break;
case KING: cout << "King";
break;
case ACE: cout << "Ace";
break;
default: cout << "Bad card face Aborting";
exit(2);
}
}

//Prompts for and fetches a hand from standard input


//returns hand sorted by value
void input ( Card hand[] )
{
using namespace std;

64
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

char suite;
Face_Value face;
for( int i = 0; i <= 4; i++)
{
cout << "Card " << i+1 << " suite: ";
cin >> suite;
cout << " " << "suite entered: " << suite << " " ;
cout << ", face: " ;
get_face( face );
cout << " face entered: ";
put_face( face );
cout << endl;
suite = tolower( suite );
hand[i].face = face;

switch ( suite )
{
case 'c': hand[i].suite = Card_Suite(0);
break;
case 'd': hand[i].suite = Card_Suite(1);
break;
case 'h': hand[i].suite = Card_Suite(2);
break;
case 's': hand[i].suite = Card_Suite(3);
break;
default: cout << "bad suite, aborting" << endl;
exit(1);
}
}

65
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

sort_hand( hand, 5 );
}

//returns true if the card values are in sequence


int is_straight (Card hand[])
{

if(hand[0].face + 1 == hand[1].face
&& hand[0].face + 2 == hand[2].face
&& hand[0].face + 3 == hand[3].face
&& hand[0].face + 4 == hand[4].face )
return 1;
else
return 0;
}

int is_flush( Card hand[] )


{
if(hand[0].suite == hand[1].suite
&& hand[1].suite == hand[2].suite
&& hand[2].suite == hand[3].suite
&& hand[3].suite == hand[4].suite )
return 1;
else
return 0;
}

int has_four(Card hand[])


{

66
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//The values are sorted, so 4 of a kind is either at the start


or the
//end of the hand!

if(hand[0].face == hand[1].face
&&hand[1].face == hand[2].face
&&hand[2].face == hand[3].face
||
hand[1].face == hand[2].face
&&hand[2].face == hand[3].face
&&hand[3].face == hand[4].face )
return 1;
else
return 0;
}

int has_three (Card hand[])


//Precondition: has_four returns false when called on this hand
//Postcondition:
//if there are 3 of a kind,
// returns true,
//else
// returns false
{

if(hand[0].face == hand[1].face
&&hand[1].face == hand[2].face
||
hand[1].face == hand[2].face

67
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

&&hand[2].face == hand[3].face
||
hand[2].face == hand[3].face
&&hand[3].face == hand[4].face )
return 1;
else
return 0;
}

//Precondition:
//Postcondition:
//if the two cards other than the three of a kind are equal,
// return true
//else
// return false

int is_full_house ( Card hand[] )


{
//Either the first three are the same and the last two are the
//same or the last three are same, and the first two are the
//same

if(hand[0].face == hand[1].face
&&hand[1].face == hand[2].face
&&hand[3].face == hand[4].face
||
hand[0].face == hand[1].face
&&hand[2].face == hand[3].face
&&hand[3].face == hand[4].face )

68
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

return 1;
else
return 0;
}

//precondition: has_four returns false.


//if two pair are in the hand, returns true
//else returns false
int has_two_pair( Card hand[])
{
if(hand[0].face == hand[1].face && //odd card is [4]
hand[2].face == hand[3].face
||
hand[0].face == hand[1].face && //odd card is [2]
hand[3].face == hand[4].face
||
hand[1].face == hand[2].face && //odd card is [0]
hand[3].face == hand[4].face )
return 1;
else
return 0;
}

//Precondition: has_four, has_three, has_two_pair all return


false
//if one pair are in the hand, returns true
//else returns false
int has_one_pair( Card hand[])
{

69
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

if ( hand[0].face == hand[1].face ||
hand[1].face == hand[2].face ||
hand[3].face == hand[4].face )
return 1;
else
return 0;
}

//lists hand in format suite, value


void output_hand( Card hand[] )
{
using namespace std;
for (int i = 0; i < 5; i++ )
{
switch( hand[i].suite )
{
case CLUBS: cout << "Clubs ";
break;
case DIAMONDS: cout << "Diamonds";
break;
case HEARTS: cout << "Hearts ";
break;
case SPADES: cout << "Spades ";
break;
default: cout << "something is WRONG - no such suite"
<< endl;
exit(1);
}
cout << '\t';

70
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

put_face( hand[i].face );
cout << endl;
}
}

//File: sort_hand.cpp
//
//Most of the changes were made with a query-search command.
//

#include <iostream.h>

enum Card_Suite { CLUBS, DIAMONDS, HEARTS, SPADES };


enum Face_Value { TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
NINE, TEN, JACK, QUEEN, KING, ACE };

struct Card
{
Card_Suite suite;
Face_Value face;
};

void sort_hand(Card a[], int number_used);


//Precondition: number_used <= declared size of the array a.
//The array elements a[0] through a[number_used - 1] have
//values.
//Postcondition: The values of a[0] through a[number_used - 1]
// have been rearranged so that
//a[0].value <= a[1].value <= ... <= a[number_used - 1].value.

71
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void swap_values(Card& v1, Card& v2);


//Interchanges the values of v1 and v2.

int index_of_smallest(const Card a[], int start_index,


int number_used);
//Precondition: 0 <= start_index < number_used.
//Referenced array elements have values.
//Returns the index i such that a[i].value is the smallest of
//the values
//a[start_index].value, a[star_index + 1].value, ...,
// a[number_used - 1].value.

//Sorts on the value key


void sort_hand(Card a[], int number_used)
{
int index_of_next_smallest;
for (int index = 0; index < number_used - 1; index++)
{//Place the correct value in a[index]:

index_of_next_smallest =
index_of_smallest(a, index, number_used);
swap_values(a[index], a[index_of_next_smallest]);
//a[0] <= a[1] <=...<= a[index] are smallest of original
//array elements. The rest of the elements are in the
//remaining positions.
}
}

72
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void swap_values(Card& v1, Card& v2)


{
Card temp;
temp = v1;
v1 = v2;
v2 = temp;
}

int index_of_smallest(const Card a[], int start_index,


int number_used)
{
Face_Value min = a[start_index].face;
int index_of_min = start_index;
for (int index = start_index + 1; index < number_used;
index++)
if (a[index].face < min)
{
min = a[index].face;
index_of_min = index;
//Assert: min is the smallest of a[start_index].face
//through a[index].face
}
return index_of_min;
}

I am including more test data than for some other problems since I discovered errors in my
code with many of these cases. In the interest of space, I am presenting only part of the output.

Data for a run to test various aspects of the program follow:


21:28:39:~/AW$ cat card_data

73
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

c k c 9 c t c j s 2
y
c 5 s a c 2 d 2 c 4
y
s 3 c k c 2 d 2 h 3
y
c t s 3 s t d t c 4
y
s k c 9 s j c q d t
y
c 2 c 8 c 7 c 3 c 5
y
h 3 s 3 c 2 d 2 c 3
y
h q c a d q c q s q
y
s a s q s k s t s j
n

The compile command used to generate the executatable is:

21:24:28:~/AW$ g++ sort_hand.cpp ch7prg8.cpp

A command that runs the program after compilation, with the above data.

21:27:30:~/AW$ a.out < card_data > card_output

Note that the output is a little nicer than the interactive run:

21:44:33:~/AW$ cat card_output


Poker Hand Evaluation Program -
Please Enter a 5 card poker hand, I'll evaluate this hand as one of
NOTHING, ONE_PAIR, TWO_PAIRS, THREE_OF_KIND, STRAIGHT FLUSH, FULL_HOUSE
FOUR_OF_KIND, or STRAIGHT_FLUSH

74
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Encode Clubs as c, Diamonds as d, Hearts as h, Spades as s


Enter the value as 2-9, t, j, q, k a, Upper case OK

Card 1 suite: suite entered: c , face: face entered: King


Card 2 suite: suite entered: c , face: face entered: 9
Card 3 suite: suite entered: c , face: face entered: 10
Card 4 suite: suite entered: c , face: face entered: Jack
Card 5 suite: suite entered: s , face: face entered: 2

Sorted hand is:


Spades 2
Clubs 9
Clubs 10
Clubs Jack
Clubs King
value of hand is: Nothing

Y/y continues, other halts.

Card 1 suite: suite entered: c , face: face entered: 5


Card 2 suite: suite entered: s , face: face entered: Ace
Card 3 suite: suite entered: c , face: face entered: 2
Card 4 suite: suite entered: d , face: face entered: 2
Card 5 suite: suite entered: c , face: face entered: 4

Sorted hand is:


Clubs 2
Diamonds 2
Clubs 4
Clubs 5
Spades Ace
value of hand is: One Pair

Y/y continues, other halts.

Card 1 suite: suite entered: s , face: face entered: 3

75
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Card 2 suite: suite entered: c , face: face entered: King


Card 3 suite: suite entered: c , face: face entered: 2
Card 4 suite: suite entered: d , face: face entered: 2
Card 5 suite: suite entered: h , face: face entered: 3

Sorted hand is:


Clubs 2
Diamonds 2
Spades 3
Hearts 3
Clubs King
value of hand is: Two Pair

Y/y continues, other halts.

Card 1 suite: suite entered: c , face: face entered: 10


Card 2 suite: suite entered: s , face: face entered: 3
Card 3 suite: suite entered: s , face: face entered: 10
Card 4 suite: suite entered: d , face: face entered: 10
Card 5 suite: suite entered: c , face: face entered: 4

Sorted hand is:


Spades 3
Clubs 4
Spades 10
Diamonds 10
Clubs 10
value of hand is: Three of a Kind

Y/y continues, other halts.

. . .

Y/y continues, other halts.

Card 1 suite: suite entered: h , face: face entered: Queen

76
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Card 2 suite: suite entered: c , face: face entered: Ace


Card 3 suite: suite entered: d , face: face entered: Queen
Card 4 suite: suite entered: c , face: face entered: Queen
Card 5 suite: suite entered: s , face: face entered: Queen

Sorted hand is:


Hearts Queen
Diamonds Queen
Clubs Queen
Spades Queen
Clubs Ace
value of hand is: Four of a Kind

Y/y continues, other halts.

Card 1 suite: suite entered: s , face: face entered: Ace


Card 2 suite: suite entered: s , face: face entered: Queen
Card 3 suite: suite entered: s , face: face entered: King
Card 4 suite: suite entered: s , face: face entered: 10
Card 5 suite: suite entered: s , face: face entered: Jack

Sorted hand is:


Spades 10
Spades Jack
Spades Queen
Spades King
Spades Ace
value of hand is: Straight Flush

Y/y continues, other halts.

Programming Project 10: tic-tac-toe

This program is to ask for moves alternately from players X and O. The display should be
board-like:

77
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

1 2 3
4 5 6
7 8 9

The players enter their moves by entering a number corresponding to the place to be
marked. After each move, the program displays the changed board. After several moves the
board may appear:

X X O
4 5 6
O 8 9

Planning:

Input,
Play
Output

This can be done with a simple one dimension array to hold the game, a play function, a
display function and a scoring function, which can be called by the play function.

The way I approached this is to have a Game class. This class has a constructor and a
play member having a char parameter, 'X' and 'O' for permissible arguments. The
class has private functions score() and display(), and a char array as a data
member.

Main declares game to be a Game object, and calls game_play(). The game_play()
function alternately calls play('X') and play('O'), the function play prompts
players for input, modifies the data in array, calls display_array(), then runs the
score() member which returns 'X' if player X wins, 'O' if player O wins, 'T' for tie,
or '\0' (NULL) for no winners.

78
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

I have a line of code that reports the number of plays remaining.

There is one additional wrinkle that is not covered in the text, but works on all systems
having a standard C/C++ library. The library call int system( char [] str )
function executes any shell command the user puts into its argument.

(A shell command is any command you use to do something at the system's prompt, $,
such as dir, ls, clear or cls, etc.)

Here I use system("clear") since most Unix systems respond to that by clearing the
screen and placing the cursor in the upper left hand position of the screen. If you are using
Windows you should use system("clear"), since the DOS command to clear the
screen is "clear".

Take care not to allow the overwriting of a position already occupied by an opponent with
one of your own. This again points out the necessity for complete testing. I finished this
problem and would have left it, were it not for my accidentally using a cell that was
already occupied. It worked. I fixed that with a loop that required the location being used
to still have a digit in it.

Take care to make your program robust. I found and fixed a couple of loops in my code
that bad input caused to go infinite.
// ********************************************************************
//
// This program plays tic-tac-toe using a 1D array to represent
// the board.
// It does not check for a win, only an end of game.
// ********************************************************************

#include <iostream>

using namespace std;

// Prototype
void showBoard(char board[]);

// This function displays a board


// on the screen. It outputs each

79
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// character in the array, putting a newline


// every three characters.
void showBoard(char board[])
{
cout << endl;
for (int i=0; i<9;i++)
{
cout << board[i] << " ";
if (((i+1) % 3) == 0) cout << endl;
}
cout << endl;
}

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

int main()
{
char board[9]; // Holds digits, X, or O
int i;
int numMoves = 0; // Number of moves
char whoseTurn = 'X'; // Current player's move
int move;

// Initialize board to character digits 1-9


for (i=0; i<9; i++)
{
board[i] = '1' + i;
}

// Get a move until all 9 moves used


while (numMoves < 9)
{
showBoard(board);
cout << "Enter move: " << endl;
cin >> move;
if ((move <1) || (move>9))
{
cout << "Invalid move, try again." << endl;
}
else
{
move--; // Our array is 0 based, not 1 based
if ((board[move]=='X') || (board[move]=='O'))
{
cout << "That space is taken. " << endl;
}
else
{
board[move] = whoseTurn;
// Switch turns
if (whoseTurn == 'X')
whoseTurn = 'O';

80
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

else
whoseTurn = 'X';
numMoves++;
}
}
}
showBoard(board);
cout << endl << "Game over!" << endl;
return 0;

Programming Project 11: Airline Seating Program.

// Airline Seating Program


// 11: Assign Passenger seating. Assume 7 rows 4 wide with
// seats assigned in this manner
//
// 1 A B D C
// 2 A B D C
// 3 A B D C
// 4 A B D C
// .
// .
// N A B D C
// .
// .
// last A B D C
//
// Program requests number of rows.the displays the seating pattern
// with an X for occupied rows
//
// 1 X B C D
// 2 A X C D
// 3 A B C D
// 4 A B X D
// .
// .
// .
// k A B C D
// .
// .
// .
// n-1 A B C D
// n A B C D
//
// The program then requests a choice of seat.
// If the seat if availabler, then the seating display is updated.
// otherwise, the program requests another choice of seat.
//
// KNOWN BUGS:
// If the user incorrectly enters the seat letter for the row
// designation, the program goes into a continuing loop. Control C
// under most operating systems stops the program. It would be a

81
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// nice enhancement to make the input more robust.

#include <iostream>
#include <cstdlib>
#include <cstddef>

//typedef char* CharArrayPtr;


//CharArrayPtr a;
//a = new char[number_of_rows];

const int NO_ROWS = 7;

typedef char SeatRow[4];

typedef SeatRow Seating[NO_ROWS];

Seating seatAssignment;

int main()
{
using std::cout;
using std::cin;
using std::endl;

Seating plan;

int row;
char seat;
int seatNo;
int r;
int s;

//Initialize seating to empty


for(r = 0; r < NO_ROWS; r++)
for (s = 0; s < 4; s++)
plan[r][s] = char ('A' + s);

cout << "Savitch Airlines\n"


<< "Seat Reservation Program.\n"
<< "Reserved seats are marked 'X'. Others are available.\n";

// Display seats
for(r = 1; r < NO_ROWS; r++)
{
for (s = 0; s < 4; s++)
{
cout << plan[r][s] << " ";
if(s == 1 )
cout << " ";

82
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

}
cout << endl;
}

char ans = 'a';


while(ans != 'n' && ans != 'N')
{
cout << "Savitch Airlines\n"
<< "Seat Reservation Program.\n"
<< "Reserved seats are marked 'X'. Others are available.\n";

cout << "Please enter your requst in the form \"3 C\" for Row 3, Seat
C\n"
<< "There are " << NO_ROWS << " rows. Seats are A, B, C, D.\n";
cin >> row >> seat;
seatNo = seat - 'A';

if('X' != plan[row][seatNo])
plan[row][seatNo] = 'X';
else
cout << "****That seat is taken****.\n****No assignment
made****.\n"
<< "****Please make another request****\n";

//Display current seating


for(r = 1; r < NO_ROWS; r++)
{
for (s = 0; s < 4; s++)
{
cout << plan[r][s] << " ";
if(s == 1 )
cout << " ";
}
cout << endl;
}
cout << "N or n quits, anyting else continues\n";
cin >> ans;

return 0;
}

/*

Typical run

Savitch Airlines
Seat Reservation Program.
Reserved seats are marked 'X'. Others are available.
A B C D

83
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

A B C D
A B C D
A B C D
A B C D
A B C D
Savitch Airlines
Seat Reservation Program.
Reserved seats are marked 'X'. Others are available.
Please enter your requst in the form "3 C" for Row 3, Seat C
There are 7 rows. Seats are A, B, C, D.
3D
A B C D
A B C D
A B C X
A B C D
A B C D
A B C D
N or n quits, anyting else continues
y
Savitch Airlines
Seat Reservation Program.
Reserved seats are marked 'X'. Others are available.
Please enter your requst in the form "3 C" for Row 3, Seat C
There are 7 rows. Seats are A, B, C, D.
3D
****That seat is taken****.
****No assignment made****.
****Please make another request****
A B C D
A B C D
A B C X
A B C D
A B C D
A B C D
N or n quits, anyting else continues
n
Press any key to continue

*/

Programming Project 14: Baby Names with Arrays


// **********************************************************************
//
// This program searches a list of the top 1000 most popular
// Baby Names from the year 2012 and outputs the popularity rank.
// It uses arrays to store the list of names.
//
//
***********************************************************************

#include <iostream>

84
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

#include <fstream>
#include <cstdlib>

using namespace std;


const int NUMNAMES=1000; // Number of names in the
file

// ======================
// main function
// ======================
int main()
{
string targetName; // Target name
string boyName, girlName; // Temp boy/girl name
int popularity; // Temp popularity
string boyNames[NUMNAMES]; // Array of boy names
string girlNames[NUMNAMES]; // Array of girl names
int boyPopularity, girlPopularity; // Popularity of match
ifstream in_stream;
int i;

// First load the names from the file into the arrays.
// Assumes the file "babynames2004.txt" is in the current directory
in_stream.open("babynames2004.txt");
if (in_stream.fail())
{
cout << "Input file opening failed." << endl;
exit(-1);
}

// Read each name from the file along with the popularity
for (i=0; i < NUMNAMES; i++)
{
// Input popularity, boy name, and girl name
in_stream >> popularity >> boyName >> girlName;
// Store in array
boyNames[i] = boyName;
girlNames[i] = girlName;
}
in_stream.close();

// Input target name


cout << "Enter the first name that you would like to find the " <<
endl;
cout << "popularity of from baby names in 2004." << endl;
cout << "Be sure to capitalize the first letter of the name." <<
endl;
cin >> targetName;
cout << endl;

// Search for name in arrays


boyPopularity = -1;
girlPopularity = -1;
for (i=0; i < NUMNAMES; i++)

85
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
if (boyNames[i] == targetName)
{
boyPopularity = i+1;
}
if (girlNames[i] == targetName)
{
girlPopularity = i+1;
}
}

// Output results
cout << targetName << " is ";
if (boyPopularity > 0)
{
cout << "ranked " << boyPopularity << " in popularity among
boys.\n";
}
else
{
cout << "not ranked among the top 1000 boy names.\n";
}
cout << targetName << " is ";
if (girlPopularity > 0)
{
cout << "ranked " << girlPopularity << " in popularity among
girls.\n";
}
else
{
cout << "not ranked among the top 1000 girl names.\n";
}
return 0;
}

Programmign Project 15: Draw Bar chart with SVG File format and arrays
// **********************************************************************
//
// This program draws a bar chart using the SVG file format.
// It uses an input array with value of -1 to signal the end of
// values to graph. It supports up to 100 entries.
//
//
***********************************************************************

#include <iostream>
#include <fstream>
#include <cstdlib>

86
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

using namespace std;

const double MAXHEIGHT = 400; // Maximum height in


pixels
const int MAXSIZE = 100; // Maximum size of
the array

// Function prototypes
int findMax(const int a[]);
void saveSVG(int a[]);

// ======================
// findMax:
// Scans through the array and returns
// the largest value in the array.
// ======================
int findMax(const int a[])
{
int i, biggestBar, curValue;

i = 0;
curValue = 0;
biggestBar = -1;
while ((curValue != -1) && (i < MAXSIZE))
{
curValue = a[i];
if (curValue > biggestBar)
{
biggestBar = a[i];
}
i++;
}
return biggestBar;
}

// ======================
// saveSVG:
// Saves the graph as an SVG file.
// ======================
void saveSVG(int bars[])
{
int i;
ofstream out_stream;
int biggestBar;
double scale;

// Find size of biggest bar


biggestBar = findMax(bars);

// Scaling factor is maxheight / biggest bar


scale = MAXHEIGHT / static_cast<double>(biggestBar);

// Multiply each bar by the scale and cast back to an Integer

87
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

for (i=0; ((i<MAXSIZE) && (bars[i]!=-1)); i++)


{
bars[i] = static_cast<int>(bars[i] * scale);
}

out_stream.open("Ch7Proj15.svg");
if (out_stream.fail())
{
cout << "Output file opening failed." << endl;
exit(-1);
}
// Output "boilerplate" for SVG files
out_stream << "<?xml version=\"1.0\" standalone=\"no\"?>" << endl;
out_stream << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"" <<
endl;
out_stream <<
"\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> " << endl;
out_stream << "<svg width=\"500\" height=\"500\"
xmlns=\"http://www.w3.org/2000/svg\">" << endl;

// Draw axis
out_stream << "<line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"" <<
MAXHEIGHT-1 << "\" " << endl;
out_stream << "style=\"stroke:purple;stroke-width:2\"/>" << endl;
out_stream << "<line x1=\"0\" y1=\"" << MAXHEIGHT-1 << "\" x2=\""
<< MAXHEIGHT-1 << "\" y2=\"" << MAXHEIGHT-1 << "\" " << endl;
out_stream << "style=\"stroke:purple;stroke-width:2\"/>" << endl;

// Draw each bar with a width of 2 so we can fit up to 100 bars.


// A nicer output would be to compute the number of bars and scale
// the width of each bar so together all of them draw in a width of
400 pixels.
for (i=0; ((i<MAXSIZE) && (bars[i]!=-1)); i++)
{
out_stream << "<rect x=\"" << (i*4)+1 << "\" y=\"" <<
MAXHEIGHT-1-bars[i] <<"\" width=\"2\" height=\"" << bars[i] << "\"" <<
endl;
out_stream << " style=\"fill:blue;\"/>";
}

// End SVG file and close


out_stream << "</svg>" << endl;
out_stream.close();
}

// ======================
// main function
// ======================
int main()
{
int bars[MAXSIZE]; // Values for bar chart
int i = 0, temp = 0;

88
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

while (temp != -1)


{
// Input bar values
cout << "Enter non-negative value for bar " << i+1 << ", -1
to exit." << endl;
cin >> temp;
bars[i] = temp;
i++;
}
saveSVG(bars);

return 0;
}

Programming Project 16: Memory Matching Game

// ****************************************************************
//
// This program implements a memory matching game.
//
// It uses a 2D array to store the cards (pairs of numbers 1-8)
// and randomly shuffles them through repeated swaps. It uses a
// second 2D array to record whether or not a card is face up or
// face down.
//
// ****************************************************************

#include <iostream>
#include <cstdlib>

const int LENGTH = 4;


const int NUM_TRIALS = 10000;

using namespace std;

// Function prototypes
void InitializeCards(int cards[][LENGTH]);
void ShowCards(int cards[][LENGTH], bool faceup[][LENGTH]);

// ======================
// InitializeCards
// Places pairs of numbers in the 2D array and then
// randomly shuffles them.
// ======================
void InitializeCards(int cards[][LENGTH])
{
int x1,y1,x2,y2;
int i;

89
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

int temp;

// Place pairs in known locations


cards[0][0]=1; cards[0][1]=1;
cards[0][2]=2; cards[0][3]=2;
cards[1][0]=3; cards[1][1]=3;
cards[1][2]=4; cards[1][3]=4;
cards[2][0]=5; cards[2][1]=5;
cards[2][2]=6; cards[2][3]=6;
cards[3][0]=7; cards[3][1]=7;
cards[3][2]=8; cards[3][3]=8;

// Randomly swap pairs 10000 times to shuffle


for (i=0; i<NUM_TRIALS; i++)
{
x1 = rand() % LENGTH;
y1 = rand() % LENGTH;
x2 = rand() % LENGTH;
y2 = rand() % LENGTH;
temp = cards[x1][y1];
cards[x1][y1]=cards[x2][y2];
cards[x2][y2] = temp;
}
}

// ======================
// ShowCards
// Generates a display on the screen. If faceup=false,
// an * is output, otherwise the card in that slot is output.
// ======================
void ShowCards(int cards[][LENGTH], bool faceup[][LENGTH])
{
int x,y;

cout << " 1 2 3 4" << endl;


cout << " =========" << endl;
for (y=0; y < LENGTH; y++)
{
cout << y+1 << " | ";
for (x=0; x< LENGTH; x++)
{
if (faceup[x][y])
{
cout << cards[x][y] << " ";
}
else
{
cout << "* ";
}
}
cout << "|" << endl;
}
cout << " =========" << endl;

90
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// ======================
// main function
// ======================
int main()
{
// Variable declarations
int cards[LENGTH][LENGTH];
bool faceup[LENGTH][LENGTH];
int x,y, temp;
int x1,y1,x2,y2;
int pairsleft = 8;

cout << "Find all the matching pairs on the board." << endl;

// Initialize faceup boolean array


for (y=0; y<LENGTH; y++)
for (x=0; x<LENGTH;x++)
{
faceup[x][y]=false;
}

// Initialize and shuffle cards on the board


InitializeCards(cards);

// Main loop, show the board


while (pairsleft > 0)
{
ShowCards(cards,faceup);
cout << "Enter an x and y position of the first card to flip." <<
endl;
cin >> x1;
cin >> y1;
cout << "Enter an x and y position of the second card to flip." <<
endl;
cin >> x2;
cin >> y2;
// Subtract one from the input, since our arrays start at 0
// but the board displays start at 1
x1--; y1--;
x2--; y2--;

// Check if we found a match


if (cards[x1][y1]==cards[x2][y2])
{
cout << "Match found!" << endl;
faceup[x1][y1]=true;
faceup[x2][y2]=true;
pairsleft--;
}
else
{

91
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// No match, but temporarily show the cards


faceup[x1][y1]=true;
faceup[x2][y2]=true;
ShowCards(cards,faceup);
cout << "Enter any number to continue." << endl;
cin >> temp;
// Hide the revealed board by scrolling it off
faceup[x1][y1]=false;
faceup[x2][y2]=false;
for (temp=0; temp<30; temp++)
{
cout << endl;
}
}
}
cout << "You found all the matching pairs! Game over." << endl;
ShowCards(cards,faceup);
}

Programming Project 17 : Swim Scheduling


// ****************************************************************
//
// Write a program with array(s) capable of storing swim schedules.
// Create a main menu that allows the user to mark a time slot as busy or
// free for either instructor. Also add an option to output the
// schedules to the screen. Next, add an option to output all time slots
// available for individual lessons (slots when at least one instructor
// is free). Finally, add an option to output all time slots available
// for group lessons (when both instructors are free).
//
// ****************************************************************

// File Name: schedule.cpp


// Author:
// Email Address:
// Project Number: 7.17
// Description: Program that manages a schedule for two
// swimming instructors.
// Last Changed: October 10, 2007

#include <iostream>

// Make constants for the number of slots each day and the number
// of days. (Such constants may be particularly useful in cases
// where we have functions that take 2-dimensional arrays as arguments,
// as a constant used in the function header will convey information
// about the order of the dimensions.)
const int NUM_SLOTS = 4;
const int NUM_DAYS = 4;

// Constants for the values that we will store in the int[][] arrays

92
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// representing each instructor's schedule


const int SLOT_OPEN = 0;
const int SLOT_FULL = 1;

// Prints a schedule to the screen


void print_schedule(int sched[][NUM_SLOTS], char openChar, char
fullChar);

// Prompts the user to select an instructor, day, and slot


void input_slot(int &instructor, int &day, int &slot);

// Prompts the user, then schedules or frees one of the instructor's


// slots. new_slot_value should be either SLOT_OPEN or SLOT_FULL.
void handle_schedule_or_free(int jeff[][NUM_SLOTS], int
anna[][NUM_SLOTS],
int new_slot_value);

int main()
{
using namespace std;

// Use arrays of ints for the schedules


int jeff[NUM_DAYS][NUM_SLOTS];
int anna[NUM_DAYS][NUM_SLOTS];
char com;

// Initialize the schedules. (Note that it would also be possible


// to initialize the 2-D array when it is declared, by listing
// all of the values. That form of initialization has not been
// discussed yet in the textbook. It may also be less scalable than
// using a loop to clear all of the values and then re-set the
// ones that are full, though that will depend on how many slots
// there are, and how many are full. The best solution is probably
// to load the initial values from an external file, rather than
// hard-coding them.)
for (int d = 0; d < NUM_DAYS; d++)
{
for (int s = 0; s < NUM_SLOTS; s++)
{
jeff[d][s] = SLOT_OPEN;
anna[d][s] = SLOT_OPEN;
}
}

jeff[0][0] = jeff[0][3]
= jeff[1][0] = jeff[1][1] = jeff[1][2] = jeff[1][3]
= jeff[2][1] = jeff[2][2] = jeff[2][3]
= jeff[3][1]
= SLOT_FULL;

anna[0][0] = anna[0][2] = anna[0][3]


= anna[1][0] = anna[1][1] = anna[1][2]
= anna[2][3]
= anna[3][0] = anna[3][1] = anna[3][3]

93
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

= SLOT_FULL;

// The main menu loop


do
{
cout << endl << "Enter one of the following commands:" << endl;
cout << " p - Print schedules" << endl;
cout << " s - Schedule a slot" << endl;
cout << " f - Free a slot" << endl;
cout << " i - Show slots available for individual lessons" << endl;
cout << " g - Show slots available for group lessons" << endl;
cout << " q - Quit" << endl;
cout << "Command: ";
cin >> com;

if ((com == 'p') || (com == 'P')) // "Print schedules"


{
cout << endl << "Jeff:" << endl;
print_schedule(jeff, '_', 'X');
cout << endl << "Anna:" << endl;
print_schedule(anna, '_', 'X');
}
else if ((com == 's') || (com == 'S')) // "Schedule a slot"
{
handle_schedule_or_free(jeff, anna, SLOT_FULL);
}
else if ((com == 'f') || (com == 'F')) // "Free a slot"
{
handle_schedule_or_free(jeff, anna, SLOT_OPEN);
}
else if ((com == 'i') || (com == 'I')) // Individual lessons
{
// Make a new schedule that has full slots where both Jeff
// and Anna are busy.
int slots[NUM_DAYS][NUM_SLOTS];

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
if ((jeff[d][s] == SLOT_FULL) && (anna[d][s] ==
SLOT_FULL))
{
slots[d][s] = SLOT_FULL;
}
else {
slots[d][s] = SLOT_OPEN;
}
}
}

cout << endl << "Slots marked with an 'I' are available "
<< "for individual lessons:" << endl << endl;
print_schedule(slots, 'I', '_');

94
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

}
else if ((com == 'g') || (com == 'G')) // Group lessons
{
// Make a new schedule that has full slots where _either_ Jeff
// and Anna are busy.
int slots[NUM_DAYS][NUM_SLOTS];

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
if ((jeff[d][s] == SLOT_FULL) || (anna[d][s] ==
SLOT_FULL))
{
slots[d][s] = SLOT_FULL;
}
else {
slots[d][s] = SLOT_OPEN;
}
}
}

cout << endl << "Slots marked with a 'G' are available "
<< "for individual lessons:" << endl << endl;
print_schedule(slots, 'G', '_');
}
}
while ((com != 'q') && (com != 'Q'));

return 0;
}

// Helper function that prints a line of the schedule


void print_schedule_line(int sched[][NUM_SLOTS], int slot, int days,
char openChar, char fullChar)
{
using namespace std;

cout << " ";


for (int i = 0; i < days; i++)
{
if (sched[i][slot] == SLOT_FULL)
{
cout << fullChar;
}
else
{
cout << openChar;
}
cout << " ";
}
cout << endl;
}

95
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

void print_schedule(int sched[][NUM_SLOTS], char openChar, char fullChar)


{
using namespace std;

cout << " Mon Tue Wed Thu" << endl;

// This would be easier if we had the slot labels in


// an array of strings, something that will be covered
// in the next chapter
cout << "11-12";
print_schedule_line(sched, 0, NUM_DAYS, openChar, fullChar);
cout << "12-1 ";
print_schedule_line(sched, 1, NUM_DAYS, openChar, fullChar);
cout << "1-2 ";
print_schedule_line(sched, 2, NUM_DAYS, openChar, fullChar);
cout << "2-3 ";
print_schedule_line(sched, 3, NUM_DAYS, openChar, fullChar);
}

// Prompts the user to select an instructor, day, and slot


void input_slot(int &instructor, int &day, int &slot)
{
using namespace std;

instructor = -1;
day = -1;
slot = -1;

// It will probably be more comfortable for the user if numbers start


// at 1 rather than 0. We'll adjust them at the end so that they
// may be used as zero-based indexes into arrays.

while ((instructor < 1) || (instructor > 2))


{
cout << "Select instructor (1 - Jeff, 2 - Anna): ";
cin >> instructor;
}

while ((day < 1) || (day > NUM_DAYS))


{
cout << "Select Day (1 - Mon, 2 - Tue, 3 - Wed, 4 - Thu): ";
cin >> day;
}

while ((slot < 1) || (slot > NUM_SLOTS))


{
cout << "Select Slot (1 - 11-12, 2 - 12-1, 3 - 1-2, 4 - 2-3): ";
cin >> slot;
}

// Adjust the user's input for zero-based indexes


instructor--;
day--;

96
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

slot--;
}

// Prompts the user, then schedules or frees one of the instructor's


// slots. new_slot_value should be either SLOT_OPEN or SLOT_FULL.
void handle_schedule_or_free(int jeff[][NUM_SLOTS], int
anna[][NUM_SLOTS],
int new_slot_value)
{
using namespace std;

int instructor, day, slot;


input_slot(instructor, day, slot);
if (instructor == 0) {
if (jeff[day][slot] == new_slot_value)
{
cout << endl << "That slot is already ";
if (new_slot_value == SLOT_OPEN)
{
cout << "free";
}
else
{
cout << "scheduled";
}
cout << "." << endl;
}
else
{
jeff[day][slot] = new_slot_value;
}
}
else
{
if (anna[day][slot] == new_slot_value)
{
cout << endl << "That slot is already ";
if (new_slot_value == SLOT_OPEN)
{
cout << "free";
}
else
{
cout << "scheduled";
}
cout << "." << endl;
}
else
{
anna[day][slot] = new_slot_value;
}
}
}

97
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

18.
// ****************************************************************
//
// Ch7Proj18.cpp
//
// Modification of the previous program to store/load schedules to disk.
//
// ****************************************************************

// File Name: schedule2.cpp


// Author:
// Email Address:
// Project Number: 7.18
// Description: Program that manages a schedule for two swimming instructors.
// This version includes the ability to save and load schedules.
// Last Changed: October 10, 2007

#include <fstream>
#include <iostream>

using namespace std;

// Make constants for the number of slots each day and the number
// of days. (Such constants may be particularly useful in cases
// where we have functions that take 2-dimensional arrays as arguments,
// as a constant used in the function header will convey information
// about the order of the dimensions.)
const int NUM_SLOTS = 4;
const int NUM_DAYS = 4;

// Constants for the values that we will store in the int[][] arrays
// representing each instructor's schedule
const int SLOT_OPEN = 0;
const int SLOT_FULL = 1;

// Prints a schedule to the screen


void print_schedule(int sched[][NUM_SLOTS], char openChar, char fullChar);

// Prompts the user to select an instructor, day, and slot


void input_slot(int &instructor, int &day, int &slot);

// Prompts the user, then schedules or frees one of the instructor's


// slots. new_slot_value should be either SLOT_OPEN or SLOT_FULL.
void handle_schedule_or_free(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS],
int new_slot_value);

// Saves the schedules to a file, prompting the user for a file name
void save(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS]);

// Loads the schedules from a file, prompting the user for a file name.
// Any data that was previously in the arrays will be overwritten.
void load(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS]);

98
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

int main()
{
using namespace std;

// Use arrays of ints for the schedules


int jeff[NUM_DAYS][NUM_SLOTS];
int anna[NUM_DAYS][NUM_SLOTS];
char com;

// Initialize the schedules. (Note that it would also be possible


// to initialize the 2-D array when it is declared, by listing
// all of the values. That form of initialization has not been
// discussed yet in the textbook. It may also be less scalable than
// using a loop to clear all of the values and then re-set the
// ones that are full, though that will depend on how many slots
// there are, and how many are full. The best solution is probably
// to load the initial values from an external file, rather than
// hard-coding them.)
for (int d = 0; d < NUM_DAYS; d++)
{
for (int s = 0; s < NUM_SLOTS; s++)
{
jeff[d][s] = SLOT_OPEN;
anna[d][s] = SLOT_OPEN;
}
}

jeff[0][0] = jeff[0][3]
= jeff[1][0] = jeff[1][1] = jeff[1][2] = jeff[1][3]
= jeff[2][1] = jeff[2][2] = jeff[2][3]
= jeff[3][1]
= SLOT_FULL;

anna[0][0] = anna[0][2] = anna[0][3]


= anna[1][0] = anna[1][1] = anna[1][2]
= anna[2][3]
= anna[3][0] = anna[3][1] = anna[3][3]
= SLOT_FULL;

// The main menu loop


do
{
cout << endl << "Enter one of the following commands:" << endl;
cout << " p - Print schedules" << endl;
cout << " s - Save the schedules to a file" << endl;
cout << " l - Load the schedules from a file" << endl;
cout << " c - Schedule a slot" << endl;
cout << " f - Free a slot" << endl;
cout << " i - Show slots available for individual lessons" << endl;
cout << " g - Show slots available for group lessons" << endl;
cout << " q - Quit" << endl;
cout << "Command: ";
cin >> com;

if ((com == 'p') || (com == 'P')) // "Print schedules"


{
cout << endl << "Jeff:" << endl;
print_schedule(jeff, '_', 'X');

99
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << endl << "Anna:" << endl;


print_schedule(anna, '_', 'X');
}
else if ((com == 'c') || (com == 'C')) // "Schedule a slot"
{
handle_schedule_or_free(jeff, anna, SLOT_FULL);
}
else if ((com == 'f') || (com == 'F')) // "Free a slot"
{
handle_schedule_or_free(jeff, anna, SLOT_OPEN);
}
else if ((com == 'i') || (com == 'I')) // Individual lessons
{
// Make a new schedule that has full slots where both Jeff
// and Anna are busy.
int slots[NUM_DAYS][NUM_SLOTS];

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
if ((jeff[d][s] == SLOT_FULL) && (anna[d][s] == SLOT_FULL))
{
slots[d][s] = SLOT_FULL;
}
else {
slots[d][s] = SLOT_OPEN;
}
}
}

cout << endl << "Slots marked with an 'I' are available "
<< "for individual lessons:" << endl << endl;
print_schedule(slots, 'I', '_');
}
else if ((com == 'g') || (com == 'G')) // Group lessons
{
// Make a new schedule that has full slots where _either_ Jeff
// and Anna are busy.
int slots[NUM_DAYS][NUM_SLOTS];

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
if ((jeff[d][s] == SLOT_FULL) || (anna[d][s] == SLOT_FULL))
{
slots[d][s] = SLOT_FULL;
}
else {
slots[d][s] = SLOT_OPEN;
}
}
}

cout << endl << "Slots marked with a 'G' are available "
<< "for individual lessons:" << endl << endl;
print_schedule(slots, 'G', '_');
}

100
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

else if ((com == 's') || (com == 'S')) // Save


{
save(jeff, anna);
}
else if ((com == 'l') || (com == 'L')) // Load
{
load(jeff, anna);
}
}
while ((com != 'q') && (com != 'Q'));

return 0;
}

// Helper function that prints a line of the schedule


void print_schedule_line(int sched[][NUM_SLOTS], int slot, int days,
char openChar, char fullChar)
{
using namespace std;

cout << " ";


for (int i = 0; i < days; i++)
{
if (sched[i][slot] == SLOT_FULL)
{
cout << fullChar;
}
else
{
cout << openChar;
}
cout << " ";
}
cout << endl;
}

void print_schedule(int sched[][NUM_SLOTS], char openChar, char fullChar)


{
using namespace std;

cout << " Mon Tue Wed Thu" << endl;

// This would be easier if we had the slot labels in


// an array of strings, something that will be covered
// in the next chapter
cout << "11-12";
print_schedule_line(sched, 0, NUM_DAYS, openChar, fullChar);
cout << "12-1 ";
print_schedule_line(sched, 1, NUM_DAYS, openChar, fullChar);
cout << "1-2 ";
print_schedule_line(sched, 2, NUM_DAYS, openChar, fullChar);
cout << "2-3 ";
print_schedule_line(sched, 3, NUM_DAYS, openChar, fullChar);
}

// Prompts the user to select an instructor, day, and slot


void input_slot(int &instructor, int &day, int &slot)
{

101
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

using namespace std;

instructor = -1;
day = -1;
slot = -1;

// It will probably be more comfortable for the user if numbers start


// at 1 rather than 0. We'll adjust them at the end so that they
// may be used as zero-based indexes into arrays.

while ((instructor < 1) || (instructor > 2))


{
cout << "Select instructor (1 - Jeff, 2 - Anna): ";
cin >> instructor;
}

while ((day < 1) || (day > NUM_DAYS))


{
cout << "Select Day (1 - Mon, 2 - Tue, 3 - Wed, 4 - Thu): ";
cin >> day;
}

while ((slot < 1) || (slot > NUM_SLOTS))


{
cout << "Select Slot (1 - 11-12, 2 - 12-1, 3 - 1-2, 4 - 2-3): ";
cin >> slot;
}

// Adjust the user's input for zero-based indexes


instructor--;
day--;
slot--;
}

// Prompts the user, then schedules or frees one of the instructor's


// slots. new_slot_value should be either SLOT_OPEN or SLOT_FULL.
void handle_schedule_or_free(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS],
int new_slot_value)
{
using namespace std;

int instructor, day, slot;


input_slot(instructor, day, slot);
if (instructor == 0) {
if (jeff[day][slot] == new_slot_value)
{
cout << endl << "That slot is already ";
if (new_slot_value == SLOT_OPEN)
{
cout << "free";
}
else
{
cout << "scheduled";
}
cout << "." << endl;
}
else
{

102
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

jeff[day][slot] = new_slot_value;
}
}
else
{
if (anna[day][slot] == new_slot_value)
{
cout << endl << "That slot is already ";
if (new_slot_value == SLOT_OPEN)
{
cout << "free";
}
else
{
cout << "scheduled";
}
cout << "." << endl;
}
else
{
anna[day][slot] = new_slot_value;
}
}
}

// Helper function that saves a single schudule to the given stream.


void save_schedule(ofstream &out, int sched[][NUM_SLOTS])
{
using namespace std;

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
out << sched[d][s] << " ";
}
}
out << '\n';
}

// Saves the schedules to a file, prompting the user for a file name
void save(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS])
{
using namespace std;

char file_name[16];
ofstream out_stream;

cout << endl << "Enter the name of a file to save the schedules to: ";
cin >> file_name;

out_stream.open(file_name);

// If we can't open the file, we'll just write an error message and
// continue. This gives the user a chance to try again, with a
// different file name. Exiting would cause the user to lose any
// changes they had made.
if (out_stream.fail())
{

103
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

cout << "ERROR: Could not open file '" << file_name << "'." << endl;
}
else
{
save_schedule(out_stream, jeff);
save_schedule(out_stream, anna);
out_stream.close();
}
}

// Helper function that loads a single schudule's worth of data from


// the given stream.
void load_schedule(ifstream &in, int sched[][NUM_SLOTS])
{
using namespace std;

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


{
for (int s = 0; s < NUM_SLOTS; s++)
{
in >> sched[d][s];
}
}
}

// Loads the schedules from a file, prompting the user for a file name.
// Any data that was previously in the arrays will be overwritten.
void load(int jeff[][NUM_SLOTS], int anna[][NUM_SLOTS])
{
using namespace std;

char file_name[16];
ifstream in_stream;

cout << endl << "Enter the name of a file to load the schedules from: ";
cin >> file_name;

in_stream.open(file_name);

// If we can't open the file, we'll just write an error message and
// continue. This gives the user a chance to try again, with a
// different file name. Exiting would cause the user to lose any
// changes they had made.
if (in_stream.fail())
{
cout << "ERROR: Could not open file '" << file_name << "'." << endl;
}
else
{
load_schedule(in_stream, jeff);
load_schedule(in_stream, anna);
in_stream.close();
}
}

Programming Project 19: Shoulder Surfing

104
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

// ****************************************************************
//
// Implementation of a shoulder-surfing resistant password that
// incorporates random challenges. The actual password is 31337.
// The digits of the entered password are extracted using / and %.
//
// ****************************************************************

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main( )
{
int actual[] = {3, 1, 3, 3, 7};
int passwordMap[10];
int enteredPassword[5];

// Generate the random digits for each password digit


srand(time(NULL));
for (int i = 0; i < 10; i++)
{
// Random number from 1-3
passwordMap[i] = (rand() % 3) + 1;
}

// Output the password mapping


cout << "Enter the digits that correspond to your secret passcode."
<< endl;
cout << "0 1 2 3 4 5 6 7 8 9" << endl;
for (int i = 0 ; i < 10; i++)
{
cout << passwordMap[i] << " ";
}
cout << endl;

// Input the 5 digit number and extract each digit into


enteredPassword
int num;
cin >> num;

// Extract each digit into enteredPassword[]


enteredPassword[4] = num % 10;
enteredPassword[3] = (num / 10) % 10;
enteredPassword[2] = (num / 100) % 10;
enteredPassword[1] = (num / 1000) % 10;
enteredPassword[0] = (num / 10000);

// Output success if every entered password value matches


// the actual password value
bool mismatch = false;
for (int i =0; i < 5; i++)

105
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

{
if (enteredPassword[i] != passwordMap[actual[i]])
mismatch = true;
}
if (mismatch)
cout << "Invalid password." << endl;
else
cout << "Your password matches! " <<
"You have been authenticated." << endl;

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


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

2. Outline of Topics in the Chapter

7.1 Introduction to Arrays


Declaring and Referencing Arrays
Arrays in Memory
Initializing Arrays

7.2 Arrays in Functions


Indexed Variables as Function Arguments
Entire Arrays as Function Arguments
The const Parameter Modifier
Functions that Return an Array

7.3 Programming with Arrays


Partially Filled Arrays

7.4 Multidimensional Arrays


Multidimensional Array Basics

106
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Multidimensional Array Parameters

3. General Remarks on the Chapter

It should be noted at this point that I have assumed g++ with Linux, specifically g++ 3.0.x
under Debian Linux as the programming environment. I have tested much of this under the
MS VC++ 6 and Borland 5.5 command compilers. Borland C++, VC++ 6.0 (and most
other compilers) give very much the same behavior as g++ and Linux for the programs
presented here.

Students that come to C++ from one of the more protective languages such as Pascal or
Java will find the low level, non-protective C/C++ array notion to be a concern at the least.
I list here are some of these concerns, and present a bit of the reasoning behind them. I
usually discuss these ideas in my class room presentation of the array concept.

7.1 Introduction to Arrays

C++ has adopted the notion of array from the C language without change. In C++ the
notion of array is quite 'low level'. By this, I mean that in C++, arrays, along with pointers
and the notion of conversion of an array name to a pointer, provide a mechanism that
closely models memory and address concepts in traditional computer hardware. The
concept is both simple and general, and has the potential to be quite efficient -- and, in
careless hands, quite dangerous.

Unlike Java and Pascal, the C++ array mechanism provides no protection against abuse and
error. Ellis and Stroustrup (ARM page 137) point out the low-level nature of C++ arrays
result in the following major limitations:

1) An array is of fixed size, with the size specified at compile time.

107
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

2) An array is one dimensional; talking about multidimensional arrays in C/C++ [only


refers] to arrays of arrays.
3) An array is not self-describing. Given a pointer to an array, there is no information to
determine the size of an array.

This last property means that passing an array as a function parameter is inherently
dangerous.

If any of the properties mentioned are a problem in programming, the programmer always
has the option to create an ADT by embedding the array in a class that overloads the
indexing [] operator to provide array bounds checking, variable array size, or otherwise
addresses the above properties that are seen as shortcomings in a given setting.

Declaring and Referencing Arrays

Be careful with the terminology. The text points out that there is much terminology
associated with the array concept, and it varies greatly from author to author. The problems
will usually be with students who have some programming experience, but not enough to
allow them to be comfortable with a change in the words used to describe these ideas.

Students who have studied languages that provide both start and ending array indices,
where both ends are usable have a particular problem with the asymmetric array bounds.
With Pascal, for example, unless a problem calls for the array indices to start at some value
other than 1, Pascal arrays traditionally start at 1 and run to the given size. On the other
hand, C/C++ arrays run from 0 to one less than the array size. The starting index is not
mentioned in the declaration, and the number that is mentioned, the size of the array, is not
a usable index value.

My students tend to confuse the use of x[4] in a declaration, as in int x[4]; with
the use of x[3] in an access to the array. I think the problem should be mentioned to your
classes. This chapter of the text discusses this idea.

108
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

As mentioned in the opening paragraph, C/C++ arrays do not provide array bounds
checking, so if array bounds are exceeded, strange results may occur.

You will hear students say "With a bad write to memory, you can cause the hard disk to be
reformatted." This isn't going to happen, especially in systems with memory protection..
My students appreciated being told this comforting bit of information. Most PCs today
have IDE controllers. These controllers do not have the capability to low-level format a
hard disk without a utility from the manufacturer. The few SCSI controllers that exist in
PCs may have disk utilities in ROM. An inadvertent write to certain addresses could
possibly start a disk utilities menu on a machine with an operating system that does not
protect memory. This is in fact unlikely, and if it did happen, it is unlikely to cause
unintended mischief.

Finally, an understanding of what happens when you index into an array based on the
memory model presented in the text is of great importance.

7.2 Arrays in Functions

Indexed Variables as Function Arguments.

An indexed array variable is just a variable having the array's base type. Hence there is
nothing special about sending it to any function that accepts such argument, except that it
looks unfamiliar.

For my students, I emphasize that the whole array is not being sent to the function, just the
element of the array indicated by the index.

PITFALL: Declaring an Array with a Non-Constant Size.

If you wanted to have an array whose size you could set at runtime, you might write the
following code. Unfortunately, this is illegal, though some compilers (including g++) allow
it.

109
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

//File: array_bounds.cpp
//To test behavior when array bounds are set, used, and
//violated
#include <iostream>
int main()
{
using namespace std;
int x[10] = {0, 1,2,3,4,5,6,7,8,9};//Ok, size is an
//int constant
int n;
cin >> n;
int y[n]; //Line 12 - Here we have (illegally) declared
//an array of non-constant size
for( int i = 0; i < n; i++)
cout << (y[i] = x[i]) << " " ;
cout<< endl;
return 0;
}

Error messages from the compiler:

g++ --pedantic array_bounds.cpp


array_bounds.cpp: In function `int main()':
array_bounds.cpp:12: warning: ANSI C++ forbids variable-size
array `y'

The C++ Standard says that the index expression must be a constant expression. The
Standard says further that a constant expression can involve only literals (such as 937,
true, or 1.23), enumerators (enum identifiers) and const values of integral types
initialized with constant expressions, sizeof expressions. We violate the rule that we must
have const integral values initialized by const expressions.

110
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

The bottom line is that array size must be known at compile time. The alternative is to
dynamically allocate space on the heap. That is treated later in the text.

Entire Arrays as Function Arguments

When passing arrays, the array name is converted to a pointer to the first array element,
hence all that the function receives is the address of the first array element. All the function
can know is the type as specified in the function declaration and the starting address of the
array but not the array size. This is sometimes referred to as “array type deterioration”.

The consequence is that passing an array parameter is not pass-by-value, since changing the
array element in the function changes the argument array element. In spite of the fact that
changing the parameter changes the caller’s argument, this is not precisely pass-by-
reference either, because the called function doesn't know the size of the array. We call this
parameter passing mechanism "passing an array parameter."

Precisely, array parameters pass the address of the first element of the array, by value.
Having the address enables the called function to change the argument by indexing the
formal parameter and making an assignment.

There are only two places in C++ where the empty array index operator may be used: one,
where an array is declared with initializers, and in an array parameter for a function:1

int x[] = { 1, 2, 3, 4, 5}; //array has 5 int elements.


void f( int formal[], int size );

The const Parameter Modifier

A reminder: A use of the const keyword is both a promise by the programmer to the
compiler and a request that the compiler hold the programmer to the promise. The promise

1
There is one other place: the delete operator applied to an array allocated on the free-store
uses empty [] indexing punctuators, but the student knows nothing of this until the pointers
chapter.

111
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

is that the programmer will not write code that can change variables affected by the
const.

The case of a class member function that is declared with the const keyword is still a
promise, but is slightly different:

int Class_name::member_function( arg_list ) const;

Here the promise is that the programmer will not to write code in this member function that
could change the calling object.

The following member declaration promises not to write code in the definition of this
function that will change the value of the parameter x in the function, which would
consequently change the caller’s argument.

int Class_name::func ( const int & x );

It is possible to return a reference from a function. This allows the function to be used as an
l-value, i.e., the function call can be assigned. If the function is declared to return a const
reference, this use of const promises not to use the function call as an l-value. We will
treat this when we deal with operator overloading, and only mention it here for
completeness.

Functions that Return an Array

Plainly put, a function cannot return an array, not really, any more than a function can
receive an array as a parameter. The parallel is exact. If we build an array inside a function
then return the array as a function value, the only thing that is returned is a pointer to a base
type object that points to the first array element. We will deal with pointers in Chapter 9.

It is worthwhile to mention to the instructor at this point that there is great danger in
returning an array from a function. There is the temptation to declare a local array in a
function, then to return a pointer to the array as the value of a function. When the function

112
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

returns, all local variables, in particular, local arrays go away. The consequence is that
memory is being referred to that is no longer allocated, indeed, may be allocated to some
other use. The problem is that if it works, then it can work for some time, only changing
when some other change is made in the code. Then subtle changes in the operation of the
program can drive someone crazy.

7.3 Programming with Arrays

The programming examples and the Case Study from the text provide more than just
illustrations of the uses of arrays as data types and as function parameters. These case
studies give examples of program design, testing, and several important algorithms of
important categories.

Case Studies and Programming Examples

Production Graph Case Study

This case illustrates top-down design, array use and array parameters, and testing. The
production array introduces the notion that it isn't necessary to use the actual numbers in a
problem as indices into arrays. Rather, this problem uses shifted plant numbers for indices.
The testing of the components of this program is an interesting study. Both top-down and
bottom-up testing are illustrated here. The all important boundary cases are tested, as well
as in-the-middle values. Boundary testing helps find off-by-one errors.

Programming Example: Partially Filled Arrays; Searching and Sorting.

This is an important section. The examples here introduce the notions of partially filled
arrays, searching and sorting. Frequently, we will know something about the largest
number of data we will need to manage, but much of the time the number of data will be
less than the maximum. We do not want to have to write a version of our analysis program
for every size of data. The tool we need is the partially filled array.

113
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Savitch Instructor’s Resource Guide
Problem Solving w/ C++, 9e Chapter 7

Searching and sorting are very important topics in Computer Science. Donald Knuth said
that much of computer science was encompassed by searching and sorting.

The algorithms presented are insertion sort and linear search. In my opinion, the simplest
reasonable algorithms ought to be the introductory examples, and this is the text’s method.
In fact, the programmer should always design for correctness and clarity first, and worry
about efficiency after it is determined by testing that the simplest solution is deficient in
speed or some other way.

"The fastest algorithm can frequently be replaced with one that is almost as fast and
much easier to understand,"

--Douglas W. Jones, University of Iowa,

Quoted in More Programming Pearls, p61, Jon Bentley, Addison Wesley,


1988.

114
Copyright © 2015 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Another random document with
no related content on Scribd:
IT almost seemed as if the guitar helped Ronald on to
perfect recovery. As the spring days advanced, his strength
increased, and Doctor Warstone's visits were discontinued.
How much I missed those visits I never owned. I think the
influence of that good man's strong nature and wise,
cheerful words had sustained me unawares. And when I lost
sight of the kind face, and ceased to hear the friendly voice,
I became conscious of my own weakness.

We had not money enough to go out of town for change


of air. Moreover, with Ronald's returning health came the
urgent need of finding work to do; and where was he to find
work if it was not to be found in London? When we were
first married I had been quite sanguine about his chance of
getting employment. He could do so many things, that it
seemed impossible for him to fail. But later on, I discovered
that the man who can do many things is precisely the man
who does fail.

He could paint a tambourine beautifully, and hang it up


on a wall with good effect; and he had a perfect genius for
arranging old china, and giving artistic touches to a room.
And there was the guitar-playing, and the singing, to say
nothing of a graceful manner and a way of gliding naturally
into the best society. Useful gifts these, were they not? Gifts
which ought, of course, to have ensured their possessor a
good income, and complete immunity from all the petty
anxieties of life!

But, alas! They did not. Days lengthened into weeks;


we left off fires, and were glad to open the windows and let
the London air enter our little room. All the best people
were in town; streets and squares were gay with carriages;
women looked charming in their freshly-donned costumes;
but I, Louie Hepburne, crept about in my shabby old gown,
carrying a heavy heart, and perpetually doing long addition
sums. Oh, those weekly bills which my good nurse never
presented! Would they ever be paid?

It was about this time that Ronald began to miss my old


cheerfulness. Somehow there were not so many things to
laugh at as there used to be. The comic side of life seemed
to be hidden from my gaze. Mental arithmetic does not
foster one's sense of humour, and the fun was gradually
dying out of my nature. I suppose I was a dull companion;
and even devotedness cannot quite make up for dulness.
One evening, when we were sitting together in our small
parlour, he looked at me and sighed.

"I don't think I acted quite fairly in persuading you to


marry me, Louie," he said, after a brief pause.

"Are you going in for vain regret, and that sort of


thing?" I asked, feeling my checks flush.

"No; but I ought to have waited till I was better off, or


—"

"Or what?" I cried, hotly. "I hate an unfinished


sentence. Shall I finish it for you? 'You ought to have waited
till you were better off, or till you had met a richer woman!'"

It was the most foolish speech that I could possibly


have made. But is there ever a loving woman who does not
at certain times say the most disastrous things? The more
she loves, the more likely she is to speak unwisely. It was
just one of those moments when a man sees that he has
the advantage, and Ronald was as quick-sighted as most
men. Moreover he, too, was by no means in his best mood
that night, although he answered with a calmness that
nearly maddened me.
"I met a richer woman long before I ever saw you," he
said, looking at me steadily to note the effect of his words.

There was a sharp pain at my heart, and the blood


rushed into my face and then receded, leaving me deadly
pale.

"Why didn't you take her?" I demanded, in a voice that


did not sound in the least like mine. "It was a pity that you
missed so good a chance."

He smiled faintly, as if my suppressed excitement


amused him.

"Well, there were obstacles in the way," he replied, in a


provokingly tranquil tone. "She had a perfect dragon of an
uncle, who was her guardian. And after some months of
futile love-making, we had to say a long good-bye."

"You did not tell me all this before we got engaged,"


said I, in my new, strange voice. "Wouldn't it have been
more honourable if you had told me that you only sought
me because you had failed in winning a girl you liked
better?"

"It would, Louie, always supposing that I had liked the


other girl better."

There was a silence, and my heart beat with quick,


heavy throbs. Until now I had never known the tremendous
power of jealousy that lay dormant within me. To the last
day of my life I shall remember the fierce agony that rent
my soul as I sat in my seat by the window, idly watching
the passers-by. What did they know of my trouble? Had any
of them ever tasted such a bitter cup as mine?

"Is she still unmarried?" I asked at last.


"Yes."

"What is her name?"

"Ida Lorimer."

I had some vague recollection of that name. It must


have been mentioned by Lady Waterville. Surely I had
heard her say something about having lost sight of an Ida
Lorimer who had been rather a favourite of hers. As I sat
and mused, a host of memories came trooping back; and
then I distinctly recalled a certain photograph in Lady
Waterville's album, and remembered the widow's languid
complaint that "Ida never came to see her now-a-days."

I was in the state of mind when bitter words are one's


sole relief. And the words that burst from my lips were as
bitter as if an evil spirit had prompted their utterance.

"It was a pity that you had to say good-bye to her! I


wish she had had to bear all that I have borne. I wish that
she were in my place at this moment!"

Of course there was but one thing for Ronald to do after


that outburst, and he did it. He got up quietly, put on his
hat, left the room, and went out of doors. In the next
moment I saw him stride past the window, with his chin
well up, and eyes looking straight ahead.

Dear heaven, what a dark cloud had suddenly


descended on the little parlour, where we had spent so
many happy hours together! It was all my fault, I told
myself; and then I got up sad wandered aimlessly into the
other room.

Before the looking-glass I came to a pause, and gazed


wearily at the reflection of my own face. I suppose it was
once a pretty face; but now the grey eyes looked at me
with an expression of infinite woe; the complexion, always
pale, had taken a sallow tinge, and even the sunny chestnut
hair was less abundant than it had been in happier days.
Nursing and anxiety had stolen away a good deal of my
youth and brightness. But Ida Lorimer had doubtless kept
all her attractions. I remembered the photograph of a fair,
calm-faced woman in evening dress, with a beautiful neck
and shoulders, and a general look of prosperity and self-
satisfaction, and the cruel fangs of jealousy began to gnaw
my heart again, and I turned away from the glass with a
low moan of pain.

By-and-by the clock struck seven, and, for the first time
since my marriage, I sat down to dinner alone. It was then
that I began to realise what it was to feed on the "bread of
affliction." Ronald's empty place deprived me of all appetite,
and the chicken, which nurse had roasted to perfection,
went back to the kitchen almost untasted. In my remorse
and loneliness, I was even more severe on myself than
there was any need to be. The vixenish wife had driven her
much-enduring husband out of doors to seek his food
elsewhere! It was quite likely that, sickened with grief and
heartache, he would go without a dinner altogether.

This last fear was about as silly a notion as ever


tormented a weak-minded woman. As a rule, the man of
unquiet mind will fly to dinner as a solace, instead of
turning from it in disgust. Quarrel with him at home, and he
rushes out to the best restaurant in Regent Street, and
consoles himself with perfect cookery. But I, being new to
men and their ways, had not then discovered all their
sources of consolation.

Moreover, I forgot that the wear and tear of Ronald's


illness, and the worry of our straitened means, had told
upon my health, and made my temper unnaturally irritable.
As I sat, dropping my foolish tears upon the table-cloth, I
did not realise the fact that I had been the chief burden-
bearer in our married life. For many weeks Ronald had had
nothing to do but get well, and accept all the petting that
was lavished upon him. I had had to work, slave, struggle
to make two ends meet, and sink down crushed under the
load of embarrassments that I could not lift alone.

Yet we were both to blame, Ronald and I. When we had


stood at the altar in St. George's Church (where so many
wealthier couples had stood before us), we had perfectly
realised that we were taking each other for better, for
worse. When there is "the little rift within the lute" you may
generally conclude that it has been made by two, not by
one alone. Patch it up before it widens, deal with the
damaged instrument as tenderly as you can, if you want to
keep its music. Even if the sounds are never again so sweet
as they used to be, they are better than the total silence
that makes all life a long regret.

The May daylight lingered long, even on the grey walls


of Chapel Place. I sat watching the slow fading of the
sunbeams, and starting at every footstep that seemed to
pause at the house door. Every knock or ring set all my
nerves quivering. Meanwhile, I prepared a hundred little
speeches of conciliation, and thought of a hundred little
ways of atoning for my unkind words; and the weary hours
crawled away, and the stars came out above the great
restless London world. Would he never return? Must I watch
and wait all through the long night?

Ten o'clock—did the clocks ever make such a dreadful


din before? I began to pace my two rooms like a wild
creature in its cage; and so another hour went by, and I had
to stop, worn-out, and sink into a seat. Eleven. Every stroke
fell like a heavy blow upon my brain.

I got up from my chair, hardly knowing what I did, and


staggered towards the door with some vague intention of
seeking nurse, and asking her what was to be done. But
just at that moment, I heard a key turn in the hall door, and
then the parlour door was suddenly flung open, and my
husband came in. With a cry that I could not repress, I
sprang up to him, and put my arms round his neck, hiding
my poor worn face on his breast.

"Oh, Ronald," I sobbed, "I have been breaking my heart


for you. Forgive my cruel words, and try to love me again!"

He folded me in a close embrace, and answered me


with fond murmurs that were more reassuring than a
thousand formal sentences. Spent and exhausted as I was,
I had seldom, perhaps never, known a happier moment
than this. The ecstasy of relief was almost more than I
could bear.

"I didn't mean to stay out so late, dear little woman,"


he said, penitently. "The fact was that I met Greystock, and
he asked me to dine with him. It's a long while since I saw
him, and we had a good many things to talk about.
Altogether, it was a lucky meeting; he is the man to give
one a helping hand, you know. But how fearfully white you
look, poor child!"

He bent over me with a face full of anxiety. Somehow


the mere mention of Greystock's name had an ominous
sound in my ears. Even in that moment, I recalled the many
plans that had failed;—the seemingly good counsel that had
led to no substantial result. In every case William Greystock
had been the planner and counsellor, and I could not
persuade myself that this meeting with him had been, as
my husband thought, a lucky meeting.

But those we love best are precisely the people who can
never be made to see with our eyes. I knew that Ronald
would not be induced to distrust Greystock at my bidding;
and as I was still smarting from the consciousness of having
spoken unadvisedly once that day, I would not commit a
second blunder. So I owned meekly that I was over-tired
and over-worn, and let Ronald soothe me and wait on me to
his heart's content.

I slept soundly that night, the heavy sleep of


exhaustion, and when I woke the next morning I had aching
limbs and a general sense of languor and weakness. Ronald
was full of anxiety, and a self-reproach which he would not
put into words. It was a rare thing for me to break down,
and it troubled him to see the effort I made to get up to
breakfast and seem like my old self.

"I wish I had not promised to go to Greystock's office


to-day," he said, regretfully. "I don't like leaving you, Louie,
although I think I have a chance of getting employment."

"Have you, really?" I asked. "Don't think of staying


indoors for me, dear; I shall be quite bright when you
return. It will be delightful to feel you are a City man, with
important business to attend to every day. You are looking
much better."

"I am gaining my strength, but you are losing yours,"


he said, kissing me, and keeping back a sigh.

We had finished breakfast, but, instead of going out at


once, he took up the guitar and ran his fingers across the
strings. Again came the soft sweet tune that had no name,
the tune which had so often haunted me in my dreams.
"What does it mean?" I cried, involuntarily.

"I don't know," he said, "I can't help asking myself the
same question every time I play it. If I could only
remember how I learnt it first, I could solve the mystery."

"I think there is something rather fascinating about the


mystery," I remarked. "That air always cheers, while it
perplexes me. It comes like a suggestion of sunshine. It
seems full of promises—promises of what? I wish I knew."

Ronald smiled at me as he put down the guitar.

"Promises of better fortune,—let us believe that," he


said. "But good fortune doesn't always come to those who
sit and wait. I am going to seek it in Greystock's office."

Again I felt a sudden heart-sinking. And yet how absurd


and unreasonable this dislike to William Greystock would
appear to others. As far as I knew, he had never done me
the slightest harm, nor had he ever crossed my path since
my marriage. Even supposing he had once been somewhat
in love with me, was that any reason why I should hate the
sound of his name? Any way, he had never pestered me
with unwelcome attentions, but had withdrawn himself
quietly when he found that my heart was not for him. And
being a strong-minded, strong-willed man, he had doubtless
conquered his fancy long ago.

Ronald took up his hat and stick, kissed me again, and


went off, whistling as gaily as a school-boy. He really had
the air of a man who was going to find good things; and I
could not help fancying that our mysterious melody had
inspired him with a cheerful spirit. And then, after he had
gone his way, the miserable experience of last night rushed
back into my mind like a flood, and, silly woman that I was,
I sat still and brooded over it.
I felt I should like to know a little more about his affair
with Ida Lorimer. But not for the world would I ever mention
her name to him again—no, not if we lived together as man
and wife for a hundred years! Yet if any one who had known
my husband in his bachelor days—Lady Waterville, for
instance—would give me some scraps of information about
him and Ida, I knew that I should fasten greedily upon
them.

Later on, I learnt that love should listen to no tales that


do not come from the loved one's own lips. But heaven only
knows what bitter hours we spend before we have mastered
that lesson.

CHAPTER VIII.
MARIAN.

IT was five in the afternoon when Ronald returned from


the city. He came home in capital spirits; but, although I
paid the closest attention to all that he said, I really could
not discover any definite ground to build a hope upon.

"When you look about you," he remarked, "you soon


find out that money-making is very easy work."

"I have already found that money-spending is very easy


work," I replied, rather dolefully.

"Don't be gloomy, Louie—for heaven's sake don't be


gloomy!" implored my husband, sinking down upon the sofa
with a groan. "How is a man to go to work if you depress
his spirit? You are a good girl, my dear, but you are always
ready with your extinguisher!"

I was a little hurt. There had been a time when He had


called me his light-bearer, guiding him out of the darkness
and perplexity of a lonely life. The falling off of poetry after
marriage has been a sore trial to many a young matron; but
few, perhaps, are quite as oversensitive as I was in those
days. The first two or three months of our wedded life had
been an idyl; then there were no curt speeches, no
sarcasms, no disagreements. But now it seemed as if we
were always saying the wrong things to each other. What
was to be done?

Some gleams of afternoon sunshine were making their


way into our little parlour, and lighting up the ancient silver
teapot and cream jug which I had brought from my faraway
home in the country. Poor relics of peaceful maiden days, I
looked at them now With misty eyes, and thought of tea-
drinkings with my girl friends, of my grandfather's
benevolent face, of the rustle of leaves outside the cottage,
and the scent of flowers that drifted in through open
windows. And suddenly and unreasonably, I was seized with
a longing to return to the old place, and see if I could find
any of the old tranquillity lingering there.

But it is not to the past that we should go if we would


find peace, for there is never anything gained by running
backward. I gave myself a mental shaking, banished the
sweet country visions and foolish yearnings, and turned to
Ronald with a smile.

"I will be as sanguine as you please," I said, brightly.


"Forgive me, dear, if I don't understand these City schemes.
I am stupid sometimes, and business matters always puzzle
me. But I have often heard Lady Waterville say that Mr.
Greystock could help you if he liked, and if you were willing
to be helped."

"Ah, that was like Lady Waterville! She used to


insinuate that I was not willing to be helped."

"Oh, Ronald, she never insinuated things! And of course


I always knew that you were anxious to get on. If Mr.
Greystock really means to assist you now, I shall never
cease thanking him."

"Of course he means to keep his word. Until to-day he


has never made a definite promise."

"Oh, then he has really promised?"

"Yes. It is a pity, Louie, that you call only believe in


demonstrative people. William Greystock is one of the most
undemonstrative men on earth; he always says less than he
means, therefore you never give him credit for any good
intentions."

My quick temper rose at these words.


"I will believe in him, Ronald," I said, "when I have seen
the fruit of those good intentions."

He started up from the sofa, and began to pace angrily


up and down the little room.

Then I was sorry that I had spoken in a bitter tone.


Only a few minutes ago I had firmly resolved to make the
very best of my life, and avoid the slightest approach to a
quarrel. And yet, here we were, on the very verge of
warfare again!

There was an uncomfortable pause. I poured out tea,


and gently pushed a cup towards him; but he took no notice
of the action. Stopping in his walk, he stood leaning against
the mantelpiece, his hands in his pockets, and his eyes
looking out into space. At that moment I saw his
resemblance to the portrait of Inez, as I had never seen it
before.

"Ronald,—" I began, timidly.

"Don't pursue the subject, Louie," he said, in a cold


tone. "I shall never ask you to believe in my friend's
intentions again, nor will I trouble you with any of my plans
for the future."

The words fell on my heart like drops of icy rain.

I tried to think of something conciliatory to say, but


nothing came to my lips, and I sat gazing helplessly at my
husband's gloomy face. After a moment's silence, he took
up his hat and moved towards the door.

"Ronald," I cried, rising suddenly, "don't stay out as you


did last night."
"No," he answered, with formal politeness, "you need
not be concerned. I shall come back at seven to dine."

The door closed behind him, and again I was left alone
with my misery. I was young, and there is a tendency in
youth to believe that every grief will be eternal.

In my turn I, too, began to pace up and down the room,


with throbbing temples and an aching heart. And when at
last tears came to my relief, I wept like a child, until I was
exhausted and utterly worn-out.

All at once I remembered that it was summer-time, and


that other people were revelling in the sunshine, while I was
sitting alone in this dim room—alone with my misery and
bitter regret. The thought set my tears flowing afresh, and
then I rose, scarcely knowing what I was doing, and began
to arrange some books and papers which were scattered
over a little table in a corner.

When I moved my blotting-book, a paper fell from


between its leaves, and fluttered down upon the floor. I
picked it up, unfolded it, and read some verses which I had
written a year ago.

"The trees are in blossom at Richmond now,


And the leaves are fresh and new;
The bloom lies thick on the lilac bough,
The clouds drift over the blue;
And the earth is as fair as it used to be
In times that have passed away;
When we shared its bliss with the bird and bee,
And laughed in the light of May.

"The trees are in blossom at Richmond now,


And the river shines like gold;
But the sweets are gone from the lilac bough,
And the skies are grey and cold;
For I miss your step in the flowery grass,
Your voice in the scented glade;
And the birds sing on, and the sweet hours pass,
Like dreams in the light and shade.

"The trees are in blossom at Richmond now,


But the flowers of love are dead;
And under the bloom of the lilac bough
I stand with a drooping head;
If I heard your voice by my side to-day,
I never could trust its tone;
And here, in the light of the sweet young May,
I live in the past alone."

When I wrote these lines, how little I knew that they


would be prophetic! But there is, I fancy, an undertone of
prophecy in every poet-nature; and even while Ronald and I
were rejoicing together under the lilac blossoms, I had
vague dreams of faded blooms and clouded skies. Now that
I read the little poem again, by the light of my new
experience, I remembered that past foreshadowing, and put
the paper away with a deep sigh of pain.

Just at that moment there was a double knock at the


hall door, which almost tempted me to believe that my
husband had returned. But no, a woman's voice was heard
asking for me; and then the door of my room was thrown
open, and the parlour-maid announced "Miss Bailey."

It was a name that called up a thousand pleasant


memories. Marian Bailey had been the playmate of my
childhood, and the companion of my early girlhood, till her
home in our village was suddenly broken up, and she had
gone to live abroad. But although I had lost sight of her, I
had never forgotten her, and the sight of her familiar face
was like a gleam of sunshine.

"What brings you here, Marian?" I said, forgetting the


traces of tears on my cheeks. "How did you find me?"

She answered that she had traced me through some of


nurse's relatives in our old village; and then her kind eyes
rested anxiously on my face for a moment. I remembered
all at once that I must present a most doleful spectacle, and
there was an awkward pause.

"I have been crying dreadfully," I admitted, taking her


hands in mine, and clinging to her as I used to cling in the
old days when anything troubled me, "Oh, Marian, how
good it is to see you again! I have been cut off so long from
everything connected with my old home that you seem to
bring me back my lost happiness."

"Don't talk so, dear," she answered, kissing me; "you


are a wife now, and you would not, I know, exchange the
present for the past. My sudden appearance has excited
you, I daresay; and, Louie, you don't look quite well.
Perhaps you want the country air."

"No," I said, wearily. "I would not exchange this smoky


old street for all the green trees and fields in the world. It is
not the country air that I want, but the peace of mind—the
freedom from care."

"My dear child," she said, sitting down on the sofa and
drawing me to her side, "we must have a long talk. As to
freedom from care, do you really think that any married
woman can reasonably expect that? I am single, you see,
and so I suppose you will be surprised at my remark. But—"

"But, Marian, you always understand people, no matter


in what state of life they are. Yes, we must indeed have a
long talk."

But Marian was not one of those people who are always
in such a hurry to gain one's confidence that they will not
give one time to open one's heart. When she had got me
beside her on the sofa, she began to talk about herself and
her own concerns, explaining the circumstances that had
brought her to London, and telling me some good news in
her own simple, natural way.

"I am no longer poor Marian Bailey," she said, gaily.


"Indeed, Louie, I hardly know myself in my new character
of rich Marian. What do you think of six hundred a year, and
a home with my old aunt in Curzon Street? It was a great
surprise to hear that my old uncle, who had never noticed
me in his life, had remembered me at his death. Then his
widow wrote to me, begging me to come and live with her;
and here I am."

"And I am very glad you are here," I answered, looking


up into her frank face, and feeling that I had got a trusty
friend.

Marian was a large woman, a little heavily-built,


perhaps, but comfortable, and pleasant to look upon. She
was not pretty, but hers was one of those good faces which
always attract you wherever you meet them. If you had
been in a land of strangers, you would have turned
instinctively to that face in your hour of need. The very
clasp of her hand had comfort in it; it was a firm hand, not
small and fragile like mine.
"How the old days come back!" she said, smiling down
at me after a little pause. "You still have your wistful eyes,
Louise; and your pretty brown hair is as bright as ever.
What a confiding child you were, and how you always clung
to me if you fancied yourself in any difficulty or danger! It
seems strange for us two to be sitting here in a London
room, doesn't it? Last time we sat together we were in the
parlour in the dear old cottage; it was summer, the doors
and windows were open, and every breeze brought in a
shower of jessamine petals and scattered them over the
floor. Your grandfather was pacing up and down his
favourite path in the garden; and you were repeating some
poem that had pleased you. When you liked verses, you
always wanted me to set them to music, and sing them."

"Oh! Marian, do you ever sing now?" I cried. "And your


dear old guitar—have you got it still?"

"Yes, I have never parted with it. Why, Louie, you have
a guitar here! Is it yours?"

"No; that is Ronald's. Ah, Marian, how I should like to


hear you sing again! Can't you remember any of your old
songs? Sing one of Moore's—something sweet and old-
fashioned—I am so tired of all our ballads of to-day. There
should not be too many deep thoughts in verses that are
written for music. A little sentiment—a little pathos—a dash
of hope—that is all that we want to sing about. There are
poems that are inscribed on our hearts with the point of a
diamond, but we do not care to sing them."

While I rambled on, Marian was running her fingers over


the strings; and suddenly I paused and started. She was
playing that strange, soft melody that Ronald had played so
often; and into her eyes there stole that musing look which
always came into his, whenever he played this air.
"What is that?" I asked, eagerly. "Ronald plays it
sometimes, but he never can think where he first heard it."

"I am trying to remember," she answered in a


thoughtful tone. The air was repeated; sweet and tender
and gay, it seemed to charm Marian just as it had charmed
us. She stopped at last with a baffled expression on her
face.

"There are words set to that air," she said, "but I cannot
recall them now. Who was it that ever played and sung this
melody to me? I wish I knew."

"That is what Ronald is always saying," I remarked. And


then I told her the story of poor Monsieur Léon, and the
way in which the guitar had come into our hands.

"I will play the air once more," she said, taking up the
guitar again. "It is very simple, but wonderfully sweet. Now
listen, and perhaps the words will come to me."

But they did not come.

Then she sang one of our old favourite ballads, and


when that was ended, I begged her to take off her bonnet
and stay to dinner.

"Aunt Baldock will be distracted," she told me. But there


was an unspoken pleading in my face that must have gone
to her heart. Perhaps she guessed that I had some special
reason for wishing her to stay that evening.

And I had indeed a special reason. For the first time in


my life, I shrank from sitting down to a tête-à-tête meal
with my husband.
Any one who is intimately acquainted with the ways of
men must know that they are never more unpleasant than
when they are acting from a sense of duty. I could fancy the
lofty moral air with which Ronald would seat himself at our
humble board. I pictured the virtuous resignation in his
manner when he ate his roast mutton, knowing all the while
that William Greystock would have given him salmon a la
maître d' hotêl and beef olives. I could imagine the
magnanimous way in which he would try to get up a little
conversation with his wife, thus letting her see that an
aggrieved man does not always bear malice, but is capable
of making the best of his condition.

But if Marian Bailey were with us, everything would be


changed for the better. She had travelled; she was musical;
she had the gift of talking pleasantly without being
positively brilliant. In short, she possessed the useful gift
(more to be desired than the ten talents) of putting people
into good humour with themselves and their surroundings.
Unselfish, even-tempered, sound in health and in heart,
Marian Bailey was born to be a blessing to herself and to
her friends; and when she had consented to stay with me, I
could await Ronald's coming with cheerfulness.

He came in, prepared to be just the man I had expected


him to be, but Marian's frank manner won his heart at once.

I left them together, and went to have a short


conference with nurse, who was always good at an
emergency. The result of that conference was that we
turned our little dinner into a sort of festival, and Ronald
gave me an approving glance across the table.

You might also like