Write solutions to the following problems involving classes and
Please write your own code. Do not copy from other solutions.
member functions using ONLY the C++ programming language.
For these questions, you will ONLY be writing the required
functions (prototyped exactly below).
The main( ) program to test your solutions will be provided for
you (also below).
SUBMISSIONS MUST NOT INCLUDE main( )
When submitting your code, you are NOT to include the main( ) function
and you may NOT add ANY additional C/C++ header files using the #include
directive other than the ones already provided with the main( ) below.
You will only be submitting the code containing YOUR solutions.
Symbolic constants using #define and any additional functions that you
wish to add may be included (provided the functions are properly prototyped).
Learning Outcomes:
After completing this lab, you will have demonstrated the ability to:
1. Edit, compile, and run C++ programs.
2. Declare, create, initialize, assign values to, and pass
class objects to functions.
3. Use .cpp files to declare and define classes.
4. Use constructors to properly initialize object data members.
6. Write C++ member functions to perform specific routines with
C++ objects.
SPECIFICATIONS:
The Mississauga Institute of Technology (M.I.T.) would like you
to demonstrate your knowledge of C++ to help them rewrite their
robotics software that was originally written in FORTRAN.
They would like you to write the code for a class called "Directive"
which will be used to encapsulate a keyword
(a string no longer than 40 characters) and a series of modifiers
(an array of 5 strings, each string being no longer than 20 characters).
// class declaration:
class Directive {
private:
char keyword[41];
char modifiers[5][21];
int wordCount, modNum;
public:
int words(const char *sentence);
int matchDirective(const char *str, const char *sentence, int wordNum);
Directive( );
Directive(const char *data);
int modifierCount( );
int validDirective(const char *phrase);
void getKeyword(char *s);
void getModifier(char *s, int pos);
};
A "Directive" has the following publicly accessible characteristics
(member functions):
int words(const char *sentence)
which returns the number of words in the string "sentence". For
the purpose of this assignment, a "word" is defined to be a sequence
of non-null, non-whitespace characters, separated from other words
by whitespace. (Recall that whitespace is any sequence of one or
more spaces, tabs and newlines).
For example,
words("Welcome to the \n \t\t\t robotics department")
returns the value 5, and
words("\n \t \t \t \n\n ")
returns 0.
int matchDirective(const char *str, const char *sentence, int wordNum)
which returns a true value if the string "str" matches the part of
the string "sentence" starting at word number "wordNum" of "sentence",
and a false value otherwise. Special rules for determining a match are
as follows:
(1) the match is case insensitive. For example, 'A' matches both
'a' and 'A'.
(2) the end of "str" must not fall in the middle of a word in
"sentence", for it to be considered a match.
(3) The word number in "wordNum" is a value starting at 1, so that
1 refers to the first word, 2 refers to the second word, and
so on. If "wordNum" is less than 0 or greater than the number in
"sentence", then no match will be found.
For example,
matchDirective("left", "Proceed three units forward and turn left", 7)
returns a true value, while
matchDirective("left", "Proceed three units forward and turn left", 3)
returns false. Similarly,
matchDirective("*r2-d2*",
"Good morning \n\t *R2-D2* & c3-p0 ", 3)
returns true, however,
matchDirective("robot",
"Welcome to the \n \t\t\t robotics department", 4)
returns false, since "robot" ends in the middle of the word "robotics".
Directive( )
This function initializes the object's keyword to "go", and its
modifiers to "north", "south", "east", "west", and "start"
in this order respectively.
Directive(const char *data)
This function is passed a constant string "data" which contains
one (1) keyword and may contain a series of up to five (5)
modifiers, each separated by the ';' semi-colon character. This
function initializes the object's keyword and its modifiers to
the values contained in the string 'data'. If more than 5 modifiers
are found in 'data', then only the first 5 are used.
An example of the constant string "data" might be:
"turn;left;right;east;west;back"
|__| |1_| |_2_| |3_| |4_| |5_|
| |_ _ _|_ _ |_ _ | _ _|_ _ series of 5 modifiers (note the order).
|
keyword
Another example of "data" might be:
"turn;left"
|__| |1_|
| |_ _ only 1 modifier
|
keyword
NOTE: You may assume that the array "data" will ALWAYS contain a
keyword, however it may contain 0, 1, 2, 3, 4, 5, 6, or n modifiers.
int modifierCount( )
This function returns the number of modifiers that have been
properly initialized in the Directive object.
int validDirective(const char *phrase)
This function will determine if any keyword or keyword-modifier
combination is present in the string "phrase".
HINT: You can use the matchDirective( ) function written earlier to
help complete this function.
The function returns the following integer values:
return combination:
value:
1 Only the keyword is present in "phrase" and no modifiers follow it.
NOTE: modifiers may precede the keyword, but are considered
meaningless and do not impact the result.
(e.g.) keyword: "turn"
modifers: "left", "right", "east", "west", "back"
Then a phrase of: "do not turn here", would return a value of 1.
2 - 6 The keyword AND a modifier are present in "phrase".
The return value here will depend on what position in the array the
modifier is located. A value of 2 will be returned when the
keyword and the first (1st) modifier are present. A value of 3 is
returned when the keyword is followed the second (2nd) modifer, etc.
NOTE: Modifiers preceding the keyword, or following the
first valid modifier are to be ignored and will not impact
the result.
(e.g.) A phrase of: "turn left here"
|__| |__|
| |_ modifier (index=0, value=1)
|
keyword (value=1)
returns a value of 2 (1 + 1).
(e.g.) A phrase of: "left turn to the west then right then go back"
|__| |__| |__| |_ _| |__|
ignored _ _ _| | | |_ __ _ _ _ _ _ _|
modifier | | |
| | ignored
| | modifiers
| |
| |_ _ 1st valid modifier found
| (index=3, value=4)
|
keyword (value=1)
returns a value of 5 (1 + 4).
0 No keyword is present in the string "phrase". Modifiers by
themselves without a keyword are considered meaningless.
NOTE: The string "phrase" can be of any size and may contain any
number of words. If more than one (1) modifier follows the
keyword, only the first modifier encountered is used.
NOTE: You are expected to use the matchDirective( ) and words( ) functions
you wrote earlier to help complete this function.
void getKeyword(char s[ ])
Fills "s" with the object's keyword. You may assume that the array "s"
will be large enough to hold the keyword.
void getModifier(char s[ ], int pos)
Fills "s" with the object's modifier at number "pos" (where a "pos"
of 0 is the first modifier, 1 is the second modifier, and so on).
You may assume that the array "s" will be large enough to hold the
modifier. If "pos" is not the number of one of the object's
modifiers, then s will be filled with an empty string ("").
MAIN PROGRAM:
///////////////////////////////////////////////////////////////////////////////
// //
// File: a1main.cpp VERSION 1.10 //
// Written By: Danny Abesdris //
// Concept By: Danny Abesdris & Evan Weaver //
// //
// Date: October 22, 2020, //
// Main program to test assignment 1 for PRG355, Fall 2021. //
// //
// You must not modify this file! //
// //
///////////////////////////////////////////////////////////////////////////////
// Your solution may ONLY use functions from the following
// included C and C++ library header files.
#include <iostream>
using namespace std;
#include <cstring>
#include <new>
#include <cctype> // for character handing functions
class Directive {
private:
char keyword[41];
char modifiers[5][21];
int wordCount, modNum;
public:
int words(const char *sentence);
int matchDirective(const char *str, const char *sentence, int wordNum);
Directive( );
Directive(const char *data);
int modifierCount( );
int validDirective(const char *phrase);
void getKeyword(char *s);
void getModifier(char *s, int pos);
};
#define SIZE 5
int checkInit(Directive &, int *, const char *, const char [ ][21], int);
void errMessage(int);
int main( ) {
char data[SIZE][121] = {
"go;north;south;east;west;start;left;right;home",
"look",
"pick-up;gold;platinum;crystal;magic-sword",
"drop;gold;platinum;crystal;magic-sword",
"attack;crystal;magic-sword"
};
char keywords[SIZE][41] = { "go", "look", "pick-up", "drop", "attack" };
char modifiers[SIZE][SIZE][21] =
{ { "north", "south", "east", "west", "start" },
{ "", "", "", "", "" },
{ "gold", "platinum", "crystal", "magic-sword", "" },
{ "gold", "platinum", "crystal", "magic-sword", "" },
{ "crystal", "magic-sword", "", "", "" }
};
char phrases[SIZE*3][81] = {
" Hello Robot! Please GO \t\t over to the \n other side.",
"Hello Robot can you \n\n\t do something? ",
"Robot \t go over to the Right, then over to the left, then start",
"Look over to the \n\n \t \t right",
"Robot, can you see what I see?",
"Did you see that? LOOK over \n there! No not there, LOOK here!\n",
"Can you pick up the platinum gold and crystal over there?",
"Over there, can you Pick-Up the \n\n \t GOLD \n?",
"OK, I will get the crystal gold platinum and pick-UP the Magic-Sword",
" drop the crystal ",
"Robot, please drop the \n\n \t\t PLATINUM ",
"Look can you see any gold platinum or crystal ?",
" Attack with the crystal and the magic sword",
"You must look around, move up then attack with the MAGIC-sword",
"ATTACK ATTACK ATTACK! First with a crystal, then with a Magic-Sword!"
};
int rvalues[SIZE*3] = { 1, 0, 6, 1, 0, 1, 0, 2, 5, 4, 3, 0, 2, 3, 1 };
int modc[SIZE] = { 5, 0, 4, 4, 2 };
int wordsInPhrase[SIZE*3] = { 9, 6, 13, 5, 7, 12, 11, 8, 12, 3, 5, 10, 8, 11, 11 };
int phraseIndex[SIZE+1] = { 2, 6, 99, 2, 7, 11 };
char wordToFind[SIZE+1][21] = { "Robot!", "something", "start", "the", "see?", "LOOK here!" };
int matchRv[SIZE+1] = { 1, 0, 0, 0, 1, 1 };
class Directive *robots[SIZE]; // SIZE number of Directive object pointers
char tData[61];
int i, j, valid=1, rc, count=0, pos=0, k, robotMods;
Directive tester;
// first check the words( ) member function
for(i=0; i<SIZE*3; i++) {
if(wordsInPhrase[i] != tester.words(phrases[i])) {
cout << "Error with your words( ) function for phrases[" << i << "]" << endl;
valid = 0;
}
}
if(valid) {
count++;
cout << "Passed test " << count << "..." << endl;
cout << "Your words( ) function worked well..." << endl;
}
// now check the matchDirective( ) member function
for(i=0; i<SIZE+1; i++) {
if(matchRv[i] != tester.matchDirective(wordToFind[i], phrases[i], phraseIndex[i])) {
cout << "Error with your matchDirective( ) function for phrases[" << i << "]" << " and word: '" << wordToFind[i] << "'" << endl;
valid = 0;
}
}
if(valid) {
count++;
cout << "Passed test " << count << "..." << endl;
cout << "Your matchDirective(...) function worked well too..." << endl;
}
for(i=0; i<SIZE; i++) {
robots[i] = NULL; // set all Directive pointers to NULL
}
for(i=0; i<SIZE && valid; i++) {
if(i==0) {
robots[i] = new Directive( ); // initializing with keyword "go", and modifiers
// "north", "south", "east", "west", and "start"
}
else {
strcpy(tData, data[i]);
robots[i] = new Directive(tData);
}
// check all Directive object keywords and modifiers
rc = checkInit(*robots[i], &count, keywords[i], modifiers[i], modc[i]);
if(rc) {
valid = 0;
}
else {
robotMods = robots[i]->modifierCount( );
cout << "Passed test " << count << "..." << endl;
cout << "robot object " << count-2 << " keyword: '" << keywords[i] << "'" << endl;
for(k=0; k<robotMods; k++)
cout << "robot object " << count-2 << " modifier[" << k << "] : '" << modifiers[i][k] << "'" << endl;
}
}
if(valid) {
count++;
for(i=0; i<SIZE && valid; i++) {
for(j=0; j<3 && valid; j++) {
rc = robots[i]->validDirective(phrases[pos]);
if(rc != rvalues[pos]) {
cout << "Program failed when testing the validDirective( ) function..." << endl;
cout << "Phrase: " << "'" << phrases[pos] << "'" << endl;
cout << "Your return value-----> " << rc << endl;
cout << "Actual return value---> " << rvalues[pos] << endl;
valid = 0;
}
else {
cout << "Passed test " << count << "..." << endl;
cout << "robot " << i+1 << " understands phrase " << pos << "... very good!" << endl;
}
count++;
pos++;
}
}
}
if(valid) {
cout << "\nCongratulations... You passed all tests!\n";
cout << "This assignment might just earn you a perfect score!!!\n";
}
else {
errMessage(count);
}
// free up ALL allocated memory
for(i=0; i<SIZE && valid; i++) {
if(robots[i] != NULL)
delete robots[i];
}
return 0;
}
int checkInit(Directive &x, int *p, const char *key, const char mod[ ][21], int mc) {
int rc, num, invalid;
char keyword[41], modifier[21];
x.getKeyword(keyword);
invalid = strcmp(key, keyword);
if(invalid) {
rc = 1;
}
if(!invalid) {
for(num=0; num<SIZE && !invalid; num++) {
x.getModifier(modifier, num);
invalid = strcmp(modifier, mod[num]);
if(invalid) {
rc = 2 + num;
}
}
}
if(!invalid) {
rc = x.modifierCount( );
if(rc != mc) {
rc = 7;
invalid = 1;
}
}
if(invalid) {
cout << "Program failed when testing the Directive( )/Directive(const char *) constructor(s)...\n";
cout << "Failed on test " << endl;
switch(rc) {
case 1:
cout << *p+1 << " with keyword " << *p+1 << " '" << key << "'\n";
cout << "Your keyword-----> " << "'" << keyword << "'\n";
cout << "Actual keyword---> " << "'" << key << "'\n";
break;
case 2:
case 3:
case 4:
case 5:
case 6:
cout << *p+1 << " with modifier " << num << " '" << mod[num-1] << "'\n";
cout << "Your modifier-----> " << "'" << modifier << "'\n";
cout << "Actual modifier---> " << "'" << mod[num-1] << "'\n";
break;
case 7:
cout << *p+1 << " on modifier count...\n";
cout << "Your modifier count-----> " << x.modifierCount( ) << "\n";
cout << "Actual modifier count---> " << mc << "\n";
break;
}
}
(*p)++;
return invalid; // returns (0) true or (1) false
}
void errMessage(int total) {
cout << "Your program passed " << total << " test(s)..." << endl;
switch(total) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
cout << "Your program still needs considerable work!\n";
break;
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
cout << "Your program still needs some work!\n";
break;
case 18:
case 19:
case 20:
case 21:
cout << "Your program is almost complete!\n";
break;
}
cout << "Keep at it!\n\n";
}
/* ========== CODE TO PLACE IN YOUR SOURCE FILE FOR SUBMISSION STARTS BELOW ========== */
// You may add your own helper functions or symbolic constants here.
// The member functions below must ALL be correctly coded
int words(const char *sentence);
int matchDirective(const char *str, const char *sentence, int wordNum);
Directive( );
Directive(const char *data);
int modifierCount( );
int validDirective(const char *phrase);
void getKeyword(char *s);
void getModifier(char *s, int pos);
// ***** NOTE: TEST YOUR PROGRAM ON YOUR OWN COMPUTER FIRST TO SEE IF THE
// OUTPUT MATCHES EXACTLY WHAT IS LISTED BELOW!!! *****
// The OUTPUT should match EXACTLY what is displayed below
// (including spaces and newlines).
Passed test 1...
Your words( ) function worked well...
Passed test 2...
Your matchDirective(...) function worked well too...
Passed test 3...
robot object 1 keyword: 'go'
robot object 1 modifier[0] : 'north'
robot object 1 modifier[1] : 'south'
robot object 1 modifier[2] : 'east'
robot object 1 modifier[3] : 'west'
robot object 1 modifier[4] : 'start'
Passed test 4...
robot object 2 keyword: 'look'
Passed test 5...
robot object 3 keyword: 'pick-up'
robot object 3 modifier[0] : 'gold'
robot object 3 modifier[1] : 'platinum'
robot object 3 modifier[2] : 'crystal'
robot object 3 modifier[3] : 'magic-sword'
Passed test 6...
robot object 4 keyword: 'drop'
robot object 4 modifier[0] : 'gold'
robot object 4 modifier[1] : 'platinum'
robot object 4 modifier[2] : 'crystal'
robot object 4 modifier[3] : 'magic-sword'
Passed test 7...
robot object 5 keyword: 'attack'
robot object 5 modifier[0] : 'crystal'
robot object 5 modifier[1] : 'magic-sword'
Passed test 8...
robot 1 understands phrase 0... very good!
Passed test 9...
robot 1 understands phrase 1... very good!
Passed test 10...
robot 1 understands phrase 2... very good!
Passed test 11...
robot 2 understands phrase 3... very good!
Passed test 12...
robot 2 understands phrase 4... very good!
Passed test 13...
robot 2 understands phrase 5... very good!
Passed test 14...
robot 3 understands phrase 6... very good!
Passed test 15...
robot 3 understands phrase 7... very good!
Passed test 16...
robot 3 understands phrase 8... very good!
Passed test 17...
robot 4 understands phrase 9... very good!
Passed test 18...
robot 4 understands phrase 10... very good!
Passed test 19...
robot 4 understands phrase 11... very good!
Passed test 20...
robot 5 understands phrase 12... very good!
Passed test 21...
robot 5 understands phrase 13... very good!
Passed test 22...
robot 5 understands phrase 14... very good!
Congratulations... You passed all tests!
This assignment might just earn you a perfect score!!!