/* Check Writer - This program display a simulated paycheck. The program asks
the user to enter the date, the payee's name, and the amount of the check
(up to $10,000). It then displays a simulated check with the dollar amount
spelled out, as in the following example:
* Date: 11/24/2014
* Pay to the Order of: Mori Yuki $1920.85
* One thousand nine hundred twenty and 85 cents
The numeric value is formatted in fixed-point notation with two decimal
places of precision. The decimal place is always displayed, even when the
number is zero or has no fractional part. String class objects are used in
this program.
Input Validation: No negative dollar amounts, or amounts over $10,000 are
accepted. */
#include "Utility.h"
#include "EvalDate.h"
char tryAgain();
void getData(string &, string &, string &);
void checkRecipient(string &);
void checkDate(string);
void checkAmount(string &);
string removePunct(string &);
string toHundred(const string *, const string *, int);
string toThousand(string, const string *, int);
string toTenThousand(string, const string *, int);
string numToWord(string);
string formatCheck(string, string &, string);
void displayCheck(string, const string, const string, const string);
int main()
{
string amount;
string dueDate;
string recipient;
string centAmount;
string wordAmount;
char again = ' ';
do
{
amount.clear();
dueDate.clear();
recipient.clear();
wordAmount.clear();
centAmount.clear();
getData(amount, dueDate, recipient);
wordAmount = formatCheck(amount, wordAmount, centAmount);
displayCheck(amount, dueDate, recipient, wordAmount);
again = tryAgain();
if (again == 'N')
{
cout << "\n\tThe Ishikawa Bank wishes to thank you for doing\n"
<< "\tbusiness with us! Have a nice day!\n\n";
}
} while (again != 'N');
pauseSystem();
return 0;
}
/* **********************************************************
Definition: getData
This function asks for the recipient's name, the check's
date, and the amount. Various tests are performed on each
item, before the contents is passed back.
********************************************************** */
void getData(string &amount, string &dueDate, string &recipient)
{
cout << "\n\n\t\t\tISHIKAWA BANK - CHECK WRITER\n\n"
<< "\n\tPlease enter the recipient's name: ";
getline(cin, recipient);
while (recipient.empty())
{
cout << "\n\tDear customer, the name field must not be empty!\n\n"
<< "\tPlease enter the recipient's name: ";
getline(cin, recipient);
}
checkRecipient(recipient);
cout << "\n\tPlease enter today's date, or date you would like\n"
<< "\tthe check cashed (Ex: 05/08/2017): ";
getline(cin, dueDate);
checkDate(dueDate);
cout << "\n\tPlease enter the desired amount: $";
getline(cin, amount);
checkAmount(amount);
}
/* **********************************************************
Definition: checkRecipient
This function performs various checks on the string object
containing the recipient's name.
********************************************************** */
void checkRecipient(string &recipient)
{
for (size_t index = 0; index < recipient.length(); index++)
{
while (!isalpha(recipient.at(0)) || ispunct(recipient[index]) ||
isdigit(recipient.at(index)) || isspace(recipient.at(0)))
{
cout << "\n\tDear customer, the name field must not be empty, and\n"
<< "\tit must not contain any numbers or punctuation marks!\n\n"
<< "\n\tPlease enter the recipient's name: ";
getline(cin, recipient);
}
}
}
/* **********************************************************
Definition: checkDate
This function checks whether the date and date-format is
correct. The function performing the checks is contained
in the header file: "EvalDate".
********************************************************** */
void checkDate(string dueDate)
{
while (evalDate(dueDate) == false)
{
cout << "\n\tDear customer, the entered date, and/or\n"
<< "\tdate-format seems to be invalid.\n\n"
<< "\tPlease enter today's date, or date you would like\n\n"
<< "\tthe check cashed (Ex: 05/08/2017): ";
getline(cin, dueDate);
evalDate(dueDate);
}
}
/* **********************************************************
Definition: checkAmount
Checks for validity of the entered amount. It must not be
lower than 0.00 or higher than 9999.99.
********************************************************** */
void checkAmount(string &amount)
{
while (stod(amount) <= 0.00 || stod(amount) > 9999.99)
{
cout << "\n\tInput Failure! Dear customer, you entered an amount\n"
<< "\tlower than 1 or greater than 9999.99. The maximum\n"
<< "\tamount is $9999.99.\n\n"
<< "\n\tPlease enter the desired amount:\t\t$";
getline(cin, amount);
}
}
/* **********************************************************
Definition: numToTword
This function "converts" numbers between 1 and 9999.99 to
words. This is achieved by accessing two arrays containing
number words, by their subscript index. The result is
stored in a string object. This string object is returned.
********************************************************** */
string numToWord(string amount)
{
const string oToTwenty[] = { "", "one ", "two ", "three ", "four ", "five ",
"six ", "seven ", "eight ", "nine ", "ten",
"eleven ", "twelve ", "thirteen ", "fourteen ",
"fifteen ", "sixteen ", "seventeen ", "eighteen ",
"nineteen " };
const string tenMult[] = { "", "", "twenty ", "thirty ", "fourty ", "fifty ",
"sixty ", "seventy ", "eighty ", "ninenty " };
int numStore = stoi(amount);
string numWord;
string words;
if (amount.length() < 3)
{
words = toHundred(oToTwenty, tenMult, numStore);
}
else if (amount.length() == 3)
{
words = toThousand(amount, oToTwenty, numStore) +
toHundred(oToTwenty, tenMult, numStore % 100);
}
else if (amount.length() == 4)
{
if (numStore % 1000 < 100)
{
words = toTenThousand(amount, oToTwenty, numStore) +
toHundred(oToTwenty, tenMult, numStore % 100);
}
else
{
words = toTenThousand(amount, oToTwenty, numStore) +
toThousand(amount, oToTwenty, numStore) +
toHundred(oToTwenty, tenMult, numStore % 100);
}
}
return numWord.append(words);
}
/* **********************************************************
Definition: toHundred
This function gets the index positions of the "tens" and
"ones" place stored in amount. It covers amounts between
1 and 99. The position is stored, and the result appended
in a string object. The string object is returned.
********************************************************** */
string toHundred(const string *oToTwenty,
const string *tenMult, int numSize)
{
string numStore;
numSize < 20 ? numStore.append(oToTwenty[numSize]) :
numStore.append(tenMult[numSize / 10] +
oToTwenty[numSize % 10]);
return numStore;
}
/* **********************************************************
Definition: toThousand
This function gets the index position of the "hundreds"
place stored in amount. This is achieved by storing the
subscript positions contained in amount, and erasing the
contents before it. The result is appended to a string
object. This string object is returned.
********************************************************** */
string toThousand(string amount, const string *oToTwenty, int numSize)
{
string numStore;
/* This if/else statement covers all sums above and below
below 1000. Depending on which, the corresponding subscript
position is extracted and stored in numSize. numSize, after
performing a calculation on it, points to the appropriate
position in the string array containing the digit in word-
form. */
if (numSize > 999)
{
numSize = stoi(amount.erase(2, 3));
numStore.append(oToTwenty[numSize % 1000 % 10] + "hundred ");
}
else
{
numSize = stoi(amount.erase(1, 2));
numStore.append(oToTwenty[numSize] + "hundred ");
}
return numStore;
}
/* **********************************************************
Definition: toTenThousand
This function gets the index position of the "thousands"
place stored in amount. This is achieved by storing the
first subscript position contained in amountm and erasing
the remaining contents. The result is appended to a string
object. This string object is returned.
********************************************************** */
string toTenThousand(string amount, const string *oToTwenty, int numSize)
{
string numStore;
numSize = stoi(amount.erase(1, 3));
return numStore.append(oToTwenty[numSize] + "thousand ");
}
/* **********************************************************
Definition: removePunct
This function does three things:
* If the user enters an amount like "256.60", the
cent amount is stored in a string object, and the
'.' is erased.
* If the user enters an amount like "256" without '.',
'00' is appended to 'centAmount'.
* If the user enters an amount like "256.2", a '0' is
appended.
The cent amount stored in the string object is returned.
********************************************************** */
string removePunct(string &amount)
{
string centAmount;
for (size_t index = 0; index < amount.length(); index++)
{
if (ispunct(amount.at(index)))
{
centAmount.append(amount, index + 1, 3);
amount.erase(index, 3);
}
}
if (centAmount.empty())
{
centAmount.append("00");
}
else if (centAmount.length() == 1)
{
centAmount.append("0");
}
return centAmount;
}
/* **********************************************************
Definition: formatCheck
This function formats the check output, and stores the
result in a string object. The string object is returned.
********************************************************** */
string formatCheck(string amount, string &wordAmount, string centAmount)
{
centAmount = removePunct(amount);
wordAmount = numToWord(amount);
wordAmount.append("dollar(s) and " + centAmount + " cents");
wordAmount.at(0) = toupper(wordAmount.at(0));
return wordAmount;
}
/* **********************************************************
Definition: displayCheck
This function outputs the formatted check to screen.
********************************************************** */
void displayCheck(string amount, const string dueDate,
const string recipient, const string wordAmount)
{
cout << fixed << showpoint << setprecision(2);
cout << "\n\t" << setw(68) << setfill('-') << "\n\n";
cout << setfill(' ') << "\n" << setw(64) << right
<< "Date: " << dueDate << "\n"
<< "\tPay to the order of: " << setw(28) << left << recipient
<< setw(2) << right << "$" << stod(amount) << "\n\n\t"
<< wordAmount << "\n\n\t"
<< "Ishikawa Bank\n\t"
<< "2-1-124 Chuo-ku\n\t"
<< "Tokyo, 105-0062\n\n\t"
<< "For: Donation" << setw(24) << "Your Signature: "
<< setw(31) << setfill('_') << "\n"
<< "\n\n\t" << setw(68) << setfill('-') << "\n";
}
/* **********************************************************
Definition: tryAgain
This function asks the user if he or she wishes to write
another check. The decision is returned.
********************************************************** */
char tryAgain()
{
char again = ' ';
cout << "\n\n\tDo you wish to write another check? (y/N): ";
cin >> again;
cin.ignore();
/* Input validation */
while (toupper(again) != 'Y' && toupper(again) != 'N')
{
cout << "\n\tDo you wish to write another check? (y/N): ";
cin >> again;
cin.ignore();
}
return toupper(again);
}
Example Output:
No comments:
Post a Comment