?
It appears that your user is supposed to type the information in, yes? So ... let the user type it in.
Printable View
?
It appears that your user is supposed to type the information in, yes? So ... let the user type it in.
Yes, the user enters the information. But the user enters it in one of the following formats:
For a volunteer,
type/firstName/lastName/employeeId
For a full time employee,
type/firstName/lastName/emloyeeId/rate/bonus
For an hourly employee,
type/firstName/lastName/emloyeeId/rate/hoursWorked
So we have to parse the information from the entered string and tokenize it. I have already done this, in the function below. I just don't know how to access the variables that I have declared in StaffMemberParser.h from my main function.
Code:// StaffMemberParser.h
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
// protections
#ifndef StaffMemberParser_H
#define StaffMemberParser_H
using namespace std;
class BadConversion : public std::runtime_error
{
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
inline double convertToDouble(const std::string& s)
{
std::istringstream i(s);
double x;
if (!(i >> x))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
inline int convertToInt(const std::string& s)
{
std::istringstream i(s);
int x;
if (!(i >> x))
throw BadConversion("convertToInt(\"" + s + "\")");
return x;
}
class StaffMemberParser
{
static StaffMember * parseStringToMember(string lineToParse)
{
const char *ptr = lineToParse.c_str();
char field [100];
int n, i = 0, hoursWorked;
string type, firstName, lastName, employeeId;
double rate, bonus;
while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
{
switch (i++)
{
case 0: type = field; break;
case 1: firstName = field; break;
case 2: lastName = field; break;
case 3: employeeId = field; break;
case 4:
if ( type == "Volunteer" )
{
// nothing to do
}
else if ( type == "HourlyEmployee" )
{
rate = convertToDouble(field);
}
else if ( type == "FullTimeEmployee" )
{
rate = convertToDouble(field);
}
break;
case 5:
if ( type == "Volunteer" )
{
// nothing to do
}
else if ( type == "HourlyEmployee" )
{
hoursWorked = convertToInt(field);
}
else if ( type == "FullTimeEmployee" )
{
bonus = convertToDouble(field);
}
break;
default: break;
}
ptr += n;
if ( *ptr != '/' )
{
break; // didn't find an expected delimiter
}
while ( *ptr == '/' )
{
++ptr; // skip the delimiter
}
}
}
};
#endif
If such a thing was necessary or desirable, that could be a problem. Since it is neither necessary nor desirable, there's no problem.Quote:
I just don't know how to access the variables that I have declared in StaffMemberParser.h from my main function.
et cetera.Code:Volunteer *new_guy = new Volunteer(firstName, lastName, employeeId);
FullTime *new_guy = new FullTime(firstName, lastName, employeeId, rate, bonus);
Okay, I tried that...but I am still getting some errors. They are as follows:
45 Assignment7.cpp expected primary-expression before '.' token
46 Assignment7.cpp 'struct std::string' has no member named 'type'
48 Assignment7.cpp `Volunteer' undeclared (first use this function)
48 Assignment7.cpp `firstName' undeclared (first use this function)
and so on with lastName and memberId.
So how do I tell the code that those variables are part of the included files so that it doesn't think they are undeclared? Also, what do those first two lines mean? Here is my code right now:
Code:// Assignment #: 7
// Name:
// EmailAddress:
// Description: It displays a menu of choices
// (add volunteers, full time employees, or hourly employees,
// compute their pay, search a member, list members,
// quit, display menu) to a user.
// Then it performs the chosen task. It will keep asking a user
// to enter the next choice until the choice of 'Q' (Quit) is
// entered.
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
#include "StaffMember.h"
#include "StaffMemberParser.h"
using namespace std;
void printMenu();
int main()
{
char input1;
string inputInfo;
bool operation;
vector<StaffMember *> memberList;
printMenu(); // print out menu
do
{
cout << "What action would you like to perform?" << endl;
cin >> input1;
switch (input1)
{
case 'A': //Add Member
cout << "Please enter a member information to add:\n";
cin >> inputInfo;
StaffMemberParser.parseStringToMember(inputInfo);
if ( inputInfo.type == "Volunteer" )
{
Volunteer *new_guy = new Volunteer(firstName, lastName, employeeId);
}
else if ( type == "HourlyEmployee" )
{
}
else if ( type == "FullTimeEmployee" )
{
FullTimeEmployee * fulltime1 = new FullTimeEmployee;
}
break;
case 'C': //Compute Pay
for (int j=0; j < memberList.size(); j++)
{
memberList.at(j)->computePay();
}
cout << "pay computed\n";
break;
case 'D': //Search for Member
cout << "Please enter a memberID to search:\n";
cin >> inputInfo;
operation = false;
for (int j=0; j < memberList.size(); j++)
{
if (inputInfo == memberList.at(j)->getMemberId())
{
operation = true;
}
else
{
operation = false;
}
}
if (operation == true)
cout << "member found\n";
else
cout << "member not found\n";
break;
case 'L': //List Members
if (sizeof(memberList) == 0)
{
cout << "no member\n" << endl;
}
else
{
for (int j=0; j < memberList.size(); j++)
{
memberList.at(j)->printInfo();
}
}
break;
case 'Q': //Quit
for (int j=0; j < memberList.size(); j++)
{
delete memberList.at(j);
}
break;
case '?': //Display Menu
printMenu();
break;
default:
cout << "Unknown action\n";
break;
}
} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read
}
/** The method printMenu displays the menu to a user **/
void printMenu()
{
cout << "Choice\t\tAction\n";
cout << "------\t\t------\n";
cout << "A\t\tAdd Member\n";
cout << "C\t\tCompute Pay\n";
cout << "D\t\tSearch for Member\n";
cout << "L\t\tList Members\n";
cout << "Q\t\tQuit\n";
cout << "?\t\tDisplay Help\n\n";
}
Hello McFly?
Code:static StaffMember * parseStringToMember(string lineToParse)
Okay..when I change that line, I get the following error on it:
45 Assignment7.cpp cannot convert `std::string' to `StaffMember*' in initialization
I am still also getting the other errors, about Volunteer and newguy not being initialized. What do I do about that?
Guh.
Since your parseStringToMember function returns a pointer to your new StaffMember, you must create the new not-a-StaffMember-but-one-of-the-derived-classes in the parseStringToMember function and not anywhere else.
Okay. So I did that, changing my parseStringToMember function so that it returns an object of one of the child classes, I think. But I am still getting some errors, and they are basically the same as before. Here are the errors I am getting:
45 Assignment7.cpp cannot convert `std::string' to `StaffMember*' in initialization
63 StaffMemberParser.h `Volunteer' undeclared (first use this function)
63 StaffMemberParser.h `vol1' undeclared (first use this function)
63 StaffMemberParser.h `Volunteer' has not been declared
and so on for each of the variables.
And then I get this error multiple times:
47 Assignment7.cpp jump to case label
45 Assignment7.cpp crosses initialization of `StaffMember*parseStringToMember'
Here are the relevant files, Assignment7.cpp and StaffMemberParser.h, with the appropriate lines being labeled:
Code:// Assignment #: 7
// Name:
// EmailAddress:
// Description: It displays a menu of choices
// (add volunteers, full time employees, or hourly employees,
// compute their pay, search a member, list members,
// quit, display menu) to a user.
// Then it performs the chosen task. It will keep asking a user
// to enter the next choice until the choice of 'Q' (Quit) is
// entered.
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
#include "StaffMember.h"
#include "StaffMemberParser.h"
using namespace std;
void printMenu();
int main()
{
char input1;
string inputInfo;
bool operation;
vector<StaffMember *> memberList;
printMenu(); // print out menu
do
{
cout << "What action would you like to perform?" << endl;
cin >> input1;
switch (input1)
{
case 'A': //Add Member
cout << "Please enter a member information to add:\n";
cin >> inputInfo;
StaffMember * parseStringToMember(inputInfo); // this is line 45
break;
case 'C': //Compute Pay
for (int j=0; j < memberList.size(); j++)
{
memberList.at(j)->computePay();
}
cout << "pay computed\n";
break;
case 'D': //Search for Member
cout << "Please enter a memberID to search:\n";
cin >> inputInfo;
operation = false;
for (int j=0; j < memberList.size(); j++)
{
if (inputInfo == memberList.at(j)->getMemberId())
{
operation = true;
}
else
{
operation = false;
}
}
if (operation == true)
cout << "member found\n";
else
cout << "member not found\n";
break;
}
} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read
}
Code:// StaffMemberParser.h
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
#include "StaffMember.h"
// protections
#ifndef StaffMemberParser_H
#define StaffMemberParser_H
using namespace std;
class BadConversion : public std::runtime_error
{
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
inline double convertToDouble(const std::string& s)
{
std::istringstream i(s);
double x;
if (!(i >> x))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
inline int convertToInt(const std::string& s)
{
std::istringstream i(s);
int x;
if (!(i >> x))
throw BadConversion("convertToInt(\"" + s + "\")");
return x;
}
class StaffMemberParser
{
static StaffMember * parseStringToMember(string lineToParse)
{
const char *ptr = lineToParse.c_str();
char field [100];
int n, i = 0, hoursWorked;
string type, firstName, lastName, employeeId;
double rate, bonus;
while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
{
switch (i++)
{
case 0: type = field; break;
case 1: firstName = field; break;
case 2: lastName = field; break;
case 3: employeeId = field; break;
case 4:
if ( type == "Volunteer" )
{
Volunteer * vol1 = new Volunteer(firstName, lastName, employeeId); // this is line 63
return vol1;
}
else if ( type == "HourlyEmployee" )
{
rate = convertToDouble(field);
}
else if ( type == "FullTimeEmployee" )
{
rate = convertToDouble(field);
}
break;
case 5:
if ( type == "Volunteer" )
{
// nothing to do
}
else if ( type == "HourlyEmployee" )
{
hoursWorked = convertToInt(field);
HourlyEmployee * hourly1 = new HourlyEmployee(firstName, lastName, employeeId, rate, hoursWorked);
return hourly1;
}
else if ( type == "FullTimeEmployee" )
{
bonus = convertToDouble(field);
FullTimeEmployee *fullTime1 = new FullTimeEmployee(firstName, lastName, employeeId, rate, bonus);
return fullTime1;
}
break;
default: break;
}
ptr += n;
if ( *ptr != '/' )
{
break; // didn't find an expected delimiter
}
while ( *ptr == '/' )
{
++ptr; // skip the delimiter
}
}
}
};
#endif
You want to call a function, not declare a variable.Code:StaffMember * parseStringToMember(inputInfo);
And I don't think I was thinking clearly: I'm pretty sure, at the top, you want
(Notice how the type means we're declaring a variable?) Then I'm pretty sure you can doCode:StaffMember * newguy;
rather than a separate pointer for each different type.Code:newguy = new Whatever_type(appropriate things here);
Okay, so like this, maybe?
I am getting an error at that line, though, so I'm guessing that is not right. Here is the error:Code:parseStringToMember(inputInfo);
45 Assignment7.cpp `parseStringToMember' undeclared (first use this function)
Okay, that makes sense. I think I get that. I am still getting a few errors, though many many less. I am getting these errors:
64 StaffMemberParser.h `Volunteer' has not been declared
84 StaffMemberParser.h `HourlyEmployee' has not been declared
90 StaffMemberParser.h `FullTimeEmployee' has not been declared
on the lines where I use the code you suggested above, though.
Here are the updated versions of my code:
Code:// Assignment #: 7
// Name:
// EmailAddress:
// Description: It displays a menu of choices
// (add volunteers, full time employees, or hourly employees,
// compute their pay, search a member, list members,
// quit, display menu) to a user.
// Then it performs the chosen task. It will keep asking a user
// to enter the next choice until the choice of 'Q' (Quit) is
// entered.
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
#include "StaffMember.h"
#include "StaffMemberParser.h"
using namespace std;
void printMenu();
int main()
{
char input1;
string inputInfo;
bool operation;
vector<StaffMember *> memberList;
printMenu(); // print out menu
do
{
cout << "What action would you like to perform?" << endl;
cin >> input1;
switch (input1)
{
case 'A': //Add Member
cout << "Please enter a member information to add:\n";
cin >> inputInfo;
parseStringToMember(inputInfo);
break;
case 'C': //Compute Pay
for (int j=0; j < memberList.size(); j++)
{
memberList.at(j)->computePay();
}
cout << "pay computed\n";
break;
default:
cout << "Unknown action\n";
break;
}
} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read
}
Code:// StaffMemberParser.h
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
#include "StaffMember.h"
// protections
#ifndef StaffMemberParser_H
#define StaffMemberParser_H
using namespace std;
class BadConversion : public std::runtime_error
{
public:
BadConversion(const std::string& s)
: std::runtime_error(s)
{ }
};
inline double convertToDouble(const std::string& s)
{
std::istringstream i(s);
double x;
if (!(i >> x))
throw BadConversion("convertToDouble(\"" + s + "\")");
return x;
}
inline int convertToInt(const std::string& s)
{
std::istringstream i(s);
int x;
if (!(i >> x))
throw BadConversion("convertToInt(\"" + s + "\")");
return x;
}
class StaffMemberParser
{
static StaffMember * parseStringToMember(string lineToParse)
{
const char *ptr = lineToParse.c_str();
char field [100];
int n, i = 0, hoursWorked;
string type, firstName, lastName, employeeId;
double rate, bonus;
StaffMember * newMember;
while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
{
switch (i++)
{
case 0: type = field; break;
case 1: firstName = field; break;
case 2: lastName = field; break;
case 3: employeeId = field; break;
case 4:
if ( type == "Volunteer" )
{
newMember = new Volunteer(firstName, lastName, employeeId); // this is line 63
return newMember;
}
else if ( type == "HourlyEmployee" )
{
rate = convertToDouble(field);
}
else if ( type == "FullTimeEmployee" )
{
rate = convertToDouble(field);
}
break;
case 5:
if ( type == "Volunteer" )
{
// nothing to do
}
else if ( type == "HourlyEmployee" )
{
hoursWorked = convertToInt(field);
newMember = new HourlyEmployee(firstName, lastName, employeeId, rate, hoursWorked);
return newMember;
}
else if ( type == "FullTimeEmployee" )
{
bonus = convertToDouble(field);
newMember = new FullTimeEmployee(firstName, lastName, employeeId, rate, bonus);
return newMember;
}
break;
default: break;
}
ptr += n;
if ( *ptr != '/' )
{
break; // didn't find an expected delimiter
}
while ( *ptr == '/' )
{
++ptr; // skip the delimiter
}
}
}
};
#endif
Okay, duh, that all makes sense. When I included my other files, I found a few more errors, but I worked my way through all of them except one. Right now, the only error I am getting is about my parser class, and looks like this:
48 StaffMemberParser.h `static StaffMember* StaffMemberParser:: parseStringToMember(std::string)' is private
45 Assignment7.cpp within this context
It is at this line:
within the Assignment7.cpp file, and at the top of the parseStringToMember function in the StaffMemberParser.h file. Am I still not calling the function correctly?Code:StaffMemberParser::parseStringToMember(inputInfo);
Thank you for all of the help, tabstop!!
Did you read what the error message says? Read what it says.
Any function you intend to call cannot be private.