String Manipulation

You have been hired as a contract programmer by the Smithfield Natural Gas company.
Your first job is to write a program that prints a form letter to customers with an overdue
account. The letter should have the form shown in Figure . When the letter is printed by
your program, however, the fields shown in brackets will be replaced by actual values.

Figure
Dear :

Our records show that your account has a balance of $ and
a past-due amount of $. Your last payment was on .
Since we haven't heard from you in some time, would you please take
a moment to send us a check for the past-due amount? We value your
business and look forward to serving you in the future.
Sincerely,

The Management P.S. If you've already sent your payment, ignore this reminder.
Inside the letter, the fields listed in Table are shown in brackets.

Table
Field Description
Salutation (either Mr. or Ms.)
Salutation
The customer’s last name
Last-Name
The customer’s total account balance
Balance
The amount the account is past due
Past-Due
The date the customer last made a payment
Date




String Manipulation
Before the letter is printed, your program should ask the user to enter values for the fields
listed in Table . The values should then be inserted into the form letter as it is being
printed. The program should perform word-wrap, which means the sentences should be
adjusted so no word is split between two lines. Additionally, the letter should have -
character left and right margins.

Variables
Table lists the major variables needed.
Table
Variable Description
Eight constant global character arrays that hold portions of the form
part...part
letter A character array to hold the salutation
salutation
A character array to hold the customer’s last name
lastName
A character array to hold the date of the last payment
lastPayment
A character array to hold the text representation of the account
balance
balance
A character array to hold the text representation of the past due
pastDue
amount
A character to hold the user’s Y or N response when asked if they wish
again
to print another letter
An integer that holds the printing position. Each time a character is
position
printed, this variable is incremented. It is used to determine when the
end of the line is near
Global Variables
The program uses eight constant global character arrays to hold the sections of the form
letter that are always the same. The arrays, named
through
, are defined and
Part
Part
initialized as follows:
const char part[] = "Dear ";
const char part[] = "Our records show that your account has a"
" balance of $";
const char part[] = " and a past due amount of $";
const char part[] = "Your last payment was on ";
const char part[] = "Since we haven't heard from you in some"
" time, would you please take a moment to send"
" us a check for the past due amount? We value"
" your business and look forward to serving you"
" in the future.\n\n";
const char part[] = "Sincerely,\n";
const char part[] = "The Management\n\n";
const char part[] = "P.S. If you've already sent your payment, ignore"
" this reminder.";



String Manipulation
NOTE:
Notice that some of the arrays are initialized with what appears to be more than
one string. For instance, look at the initialization of
:
part
const char part[] = "Our records show that your account has a"
" balance of $";
The two strings are actually concatenated into one string. This allows the pogrammer to
easily span multiple lines when initializing character arrays with long strings. The same
technique is used with
and
.
part
part
Modules
The program will consist of the functions listed in Table .
Table
Function Description
The program’s
function. Calls the
and
main
main
getInfo
printLetter
functions.
Calls the
function to get the salutation. Then asks the user to enter
getInfo
getSal
the customer’s last name, account balance, past-due amount, and date of
last payment.
Prints a menu allowing the user to select either Mr. or Ms. as the
getSal
salutation.
Controls the printing of the form letter once the fields have been input by
printLetter
the user. Calls the
function.
printLine
Prints a line of text starting at the current printing position. This function
printLine
performs word-wrap when near the end of the line. It keeps the
position
variable updated as well.
Function
main
Function
contains the array definitions for the salutation, last name, date of last pay-
main
ment, account balance, and past due amount. A
loop calls the
and
do-while
getInfo
functions. The loop repeats as long as the user wishes to print form letters.
printLetter
Here is the pseudocode:
Do
Call getInfo to get the salutation, last name, balance, past-due
amount, and date of last payment from the user.
Call printLetter to print the form letter.
Ask the user if another letter is to be printed.
While the user wants to print another letter.



String Manipulation
Here is the function’s actual C++ code:
int main()
{
char salutation[]; // To hold the salutation
char lastName[]; // Customer's last name
char lastPayment[]; // Date of last payment
char balance[]; // Account balance
char pastDue[]; // Amount past due
char again; // To hold Y or N
do
{
// Call getInfo to get input from the user
getInfo(salutation, lastName, balance, pastDue,
lastPayment);
cout << "\n\n";
// Now print the form letter
printLetter(salutation, lastName, balance, pastDue,
lastPayment);
cout << "\n\nDo another letter? (Y/N) ";
cin >> again;
} while (toupper(again) == 'Y');
return ;
}
Notice that pointers to
,
,
,
, and
salutation
lastName
balance
pastDue
lastPayment
are passed to
and
. When
returns, these fields will have
getInfo
printLetter
getInfo
the values provided by the user stored in them.
will retrieve the values and
printLetter
insert them in the form letter.
The
getInfo
Function
This function first calls the
function (to get the salutation), and then asks the user
getSal
to enter the customer’s last name, account balance, past due amount, and the date of the
last payment. These values are then stored in the arrays whose addresses are passed into
the function as arguments. Here is the pseudocode:
Call getSal.
Ask the user to enter the customer’s last name.
Convert the first character of the last name to upper case.
Ask the user to enter the customer’s account balance.
Ask the user to enter the account’s past due amount.
Ask the user to enter the date of the last payment.
Notice that after the user enters the customer’s last name, the function automatically con-
verts its first character to upper case. This is in case the user entered the name in all lower
case. Here is the function’s C++ code:
void getInfo(char *sal, char *lname, char *bal, char *due,
char *lastPay)
{
getSal(sal);
cout << "Last name: ";
cin >> lname;



String Manipulation
lname[] = toupper(lname[]);
cout << "Account balance: ";
cin >> bal;
cout << "Past due amount: ";
cin >> due;
cout << "Date of last payment(MM/DD/YYYY): ";
cin >> lastPay;
}
The
getSal
Function
This function displays a menu allowing the user to select a salutation from either Mr. or
Ms. The choice is then stored in the array whose address is passed into the function as an
argument. Here is the pseudocode:
Do
Display menu with choice being Mr. and choice being Ms.
Ask user to select a salutation.
While the user does not select or from the menu.
If the user selected
The salutation is Mr.
else
The salutation is Ms.
End If.
Here is the function’s C++ code:
void getSal(char *sal)
{
int choice;
do
{
cout << "Salutation:\n";
cout << "\t) Mr.\n";
cout << "\t) Ms.\n";
cout << "Select one: ";
cin >> choice;
} while (choice != && choice != );
if (choice == )
strcpy(sal, "Mr.");
else
strcpy(sal, "Ms.");
}
The
printLetter
Function
Once the user has entered values for all the fields, this function controls the printing of the
letter. It has one local variable,
, which is an integer. This variable keeps track of
position
the number of characters printed on the current line. This is crucial information for the
function, which performs word-wrap. Below is the function’s pseudocode. (It
printLine
might help you to refer to the contents of the global arrays
through
as you
Part
Part
read the code.)



String Manipulation
// First print the salutation part of the letter.
Set the position variable to (for printLine).
Call printLine to print the part array.
Print the salutation, followed by a space, followed by the
customer’s last name, followed by a colon.
// Next print the body of the letter.
Set the position variable to zero.
Call printLine to print the part array.
Print the customer’s balance.
Adjust the position variable.
Call printLine to print the part array.
Print the past-due amount.
Adjust the position variable.
Call printLine to print the part array.
Print the date of the last payment.
Adjust the position variable.
Call printLine to print the part array.
// Next print the letter’s closing.
Set the position variable to zero (to start a new line.)
Call printLine to print the part array.
Set the position variable to zero (to start a new line).
Call printLine to print the part array.
// Last, print the PS reminder.
Set the position variable to zero (to start a new line).
Call printLine to print the part array.
The
function updates the
variable. When
prints one
printLine
position
PrintLetter
of the fields, such as balance, it must adjust the position variable. This is so the
function will accurately detect the end of each line. Notice that every time a
printLine
new line is to be started,
is reset to zero. Here is the C++ code for the function:
position
void printLetter(char *sal, char *lname, char *bal, char *due,
char *lastPay)
{
int position;
// Print the salutation part of the letter
position = ; // Start a new line
printLine(part, position);
cout << sal << " " << lname << ":" << endl << endl;
// Print the body of the letter
position = ; // Start a new line.
printLine(part, position);
cout << bal; // Print account balance.
// Add length of balance to position.
position += strlen(bal);
printLine(part, position);
cout << due << ". "; // Print past due amount
position += strlen(due)+ ;
// Add length of due and the period and space at the
// end of the sentence to position.
printLine(part, position);
cout << lastPay << ". "; // Print date of last payment.



String Manipulation
// Now Add length of lastPay and the period and space at the
// end of the sentence to position.
position += strlen(lastPay) + ;
printLine(part, position);
// Print the closing
position = ; // Start a new line
printLine(part, position);
position = ; // Start a new line
printLine(part, position);
// Print the PS reminder
position = ; // Start a new line
printLine(part, position);
}
The printLine Function
This function prints each individual line of the letter. It takes two arguments: the address
of the string that is to be printed on the line, and the variable used to store the number of
characters printed (the
variable). The number of characters printed on the line
position
is important because the program must perform word-wrap. This happens when the word
being printed at the end of a line will not entirely fit. Instead of printing part of the word
on one line and then continuing it on the next line, the program is to start the word on the
next line. Here is the function’s pseudocode:
If the line is at or past the right margin
Start a new line.
End If.
While not at the end of the string
If or more characters have been printed AND the next
character is a space
Perform word-wrap.
End If.
If at the beginning of a new line
Print the left margin ( spaces).
Add to the number of characters printed.
End If.
Print the next character.
Add one to the number of characters printed.
End While.
The first
statement simply checks to see if the current printing position is at or beyond
if
the right margin. Because the letter has ten-character margins, any position beyond the
th character is in the right margin.
Inside the
loop another
statement checks to see if or more characters have
while
if
been printed. This is the part that controls word-wrap. The function begins watching for a
space separating words at the th character. If a break between two words appears any-
where after the th character, a new line is started. The next
statement checks to see
if
a new line has begun. If so, it prints the spaces that make the left margin. After all
if
this has taken place, the next character is printed and the character count is incremented.



String Manipulation
Here is the C++ code for the function:
void printLine(const char *line, int &startCount)
{
int charCount = ;
if (startCount >= ) // If the line is already at
{ // or past the right margin...
cout << "\n"; // Start a new line.
startCount = ; // Reset startCount.
}
// The following while loop cycles through the string
// printing it one character at a time. It watches for
// spaces after the th position so word-wrap may be
// performed.
while (line[charCount] != '\')
{
if (startCount >= && line[charCount] == ' ')
{
cout << " \n"; // Print right margin.
charCount++; // Skip over the space
startCount = ;
}
if (startCount == )
{
cout << " "; // Print left margin.
startCount = ;
}
cout.put(line[charCount]); // Print the character.
charCount++; // Update subscript.
startCount++; // Update position counter.
}
}
NOTE:
The
parameter is a reference to the
variable in the
startCount
position
function.
printLetter
The Entire Program
Program - shows the entire program’s source code.



String Manipulation
Program -

// This program prints a simple form letter reminding a customer

// of an overdue account balance.

#include

#include

#include

using namespace std;


// Function Prototypes

void printLetter(char *, char *, char *, char *, char *);

void getInfo(char *, char *, char *, char *, char *);

void getSal(char *);

void printline(const char *, int&);


// Strings that make up the form letter

const char part[] = "Dear ";

const char part[] = "Our records show that your account has a"

" balance of $";

const char part[] = " and a past due amount of $";

const char part[] = "Your last payment was on ";

const char part[] = "Since we haven't heard from you in some"

" time, would you please take a moment to send"

" us a check for the past due amount? We value"

" your business and look forward to serving you"

" in the future.\n\n";

const char part[] = "Sincerely,\n";

const char part[] = "The Management\n\n";

const char part[] = "P.S. If you've already sent your payment, ignore"

" this reminder.";


int main()

{

char salutation[]; // To hold the salutation

char lastName[]; // Customer's last name

char lastPayment[]; // Date of last payment

char balance[]; // Account balance

char pastDue[]; // Amount past due

char again; // To hold Y or N


do

{

// Call getInfo to get input from the user

getInfo(salutation, lastName, balance, pastDue,

lastPayment);

cout << "\n\n";

// Now print the form letter

printLetter(salutation, lastName, balance, pastDue,

lastPayment);

cout << "\n\nDo another letter? (Y/N) ";

cin >> again;

} while (toupper(again) == 'Y');

return ;

}

(program continues)



String Manipulation
Program -
(continued)

//*****************************************************************

// Definition of function getInfo. *

// This function allows the user to enter the following items: *

// salutation, last name, account balance, past due amount, and *

// date of last payment. The function arguments are pointers to *

// strings where the input will be stored. *

//*****************************************************************


void getInfo(char *sal, char *lname, char *bal, char *due,

char *lastPay)

{

getSal(sal);

cout << "Last Name: ";

cin >> lname;

lname[] = toupper(lname[]);

cout << "Account balance: ";

cin >> bal;

cout << "Past due Amount: ";

cin >> due;

cout << "Date of last payment (MM/DD/YYYY): ";

cin >> lastPay;

}


//****************************************************************

// Definition of function getSal. *

// This function gives the user a menu from which to pick a *

// suitable title for the letter's addressee. The choices are *

// Mr. and Ms. The choice will be copied to the address pointed *

// to by sal. *

//****************************************************************


void getSal(char *sal)

{

int choice;


do

{

cout << "salutation:\n";

cout << "\t) Mr.\n";

cout << "\t) Ms.\n";

cout << "Select one: ";

cin >> choice;

} while (choice != && choice != );


if (choice == )

strcpy(sal, "Mr.");

else

strcpy(sal, "Ms.");

}

(program continues)



String Manipulation
Program -
(continued)

//*************************************************************

// Definition of function printLetter. *

// This function prints the form letter. The parameters are *

// pointers to the fields that contain user input. *

//*************************************************************


void printLetter(char *sal, char *lname, char *bal, char *due,

char *lastPay)

{

int position;


// Print the salutation part of the letter

position = ; // Start a new line.

printline(part, position);

cout << sal << " " << lname << ":" << endl << endl;


// Print the body of the letter

position = ; // Start a new line.

printline(part, position);

cout << bal; // Print account balance.


// Add length of balance to position.

position += strlen(bal);

printline(part, position);

cout << due << ". "; // Print past due amount

position += strlen(due)+ ;


// Add length of due and the period and space at the

// end of the sentence to position.

printline(part, position);

cout << lastPay << ". "; // Print date of last payment.


// Now Add length of lastPay and the period and space at the

// end of the sentence to position.

position += strlen(lastPay) + ;

printline(part, position);


// Print the closing.

position = ; // Start a new line.

printline(part, position);

position = ; // Start a new line.

printline(part, position);


// Print the PS reminder.

position = ; // Start a new line.

printline(part, position);

}

(program continues)



String Manipulation
Program -
(continued)

//*******************************************************************

// Definition of function printline. *

// This function has two parameters: line and startCount. *

// The string pointed to by line is printed. startCount is the *

// starting position of the line in an character field. There *

// are -character left and right margins within the *

// character field. The function performs word-wrap by looking *

// for space character within the line at or after the th *

// character. A new line is started when a space is found, or the *

// end of the field is reached. *

//*******************************************************************


void printline(const char *line, int &startCount)

{

int charCount = ;


if (startCount >= ) // If the line is already at

{ // or past the right margin...

cout << "\n"; // Sart a new line.

startCount = ; // Reset startCount.

}


// The following while loop cycles through the string

// printing it one character at a time. It watches for

// spaces after the th position so word-wrap may be

// performed.

while (line[charCount] != '\')

{

if (startCount >= && line[charCount] == ' ')

{

cout << " \n"; // Print right margin.

charCount++; // Skip over the space.

startCount = ;

}

if (startCount == )

{

cout << " "; // Print left margin.

startCount = ;

}

cout.put(line[charCount]); // Print the character.

charCount++; // Update subscript.

startCount++; // Update position counter.

}

}



String Manipulation
Program -
(continued)
Program Output with Example Input Shown in Bold
Salutation:
) Mr.
) Ms.
Select one:
[Enter]
Last name:
Jones [Enter]
Account balance:
. [Enter]
Past due amount:
. [Enter]
Date of last payment(MM/DD/YYYY):
// [Enter]
Dear Mr. Jones:
Our records show that your account has a balance of
$. and a past due amount of $.. Your last
payment was on //. Since we haven't heard from
you in some time, would you please take a moment to
send us a check for the past-due amount? We value your business
and look forward to serving you in the future.
Sincerely,
The Management
P.S. If you've already sent your payment, ignore this
reminder.
Do another letter? (Y/N)
y [Enter]
Salutation:
) Mr.
) Ms.
Select one:
[Enter]
Last name:
Hildebrand [Enter]
Account balance:
,. [Enter]
Past due amount:
,. [Enter]
Date of last payment(MM/DD/YYYY):
// [Enter]
Dear Ms. Hildebrand:
Our records show that your account has a balance of
$,. and a past due amount of $,.. Your
last payment was on //. Since we haven't heard
from you in some time, would you please take a moment
to send us a check for the past-due amount? We value
your business and look forward to serving you in the
future.
Sincerely,
The Management
P.S. If you've already sent your payment, ignore this
reminder.
Do another letter? (Y/N)
n [Enter]