Hello! Thank you for taking the time to help me out! I am working on a program that maintains information about staff members, such as volunteers, and full time and hourly employees. I am having two problems with the program.

First, I have most of the code written already, except for the header file that is supposed to parse a string for the other header files. I really don't know how to do this file, because I am unsure how to tokenize the input string. The file is described in the assignment documentation as follows:

The StaffMemberParser class is a utility class that will be used to create a pointer to a staff member object (one of a volunteer object, a full time employee object, and an hourly employee object) from a parsable string. The StaffMemberParser class object will not be instantiated. It must have the following public function:

static StaffMember * parseStringToMember(string lineToParse)

Here is what I have so far for that file, which isn't much:

// StaffMemberParser.h

// protections 
#ifndef StaffMemberParser_H
#define StaffMemberParser_H

using namespace std;

class StaffMemberParser
{
      static StaffMember * parseStringToMember(string lineToParse)
      {
             
      }

};

#endif

Second, I am getting an error when I compile the files I do have done, which does not relate to this file at all. The error is as follows:
23 StaffMember.h expected `)' before ',' token
Why am I getting this error? How can I fix it? Here is the StaffMember.h file for your reference:

// StaffMember.h
// Assignment #: 7
// Name: Rebecca Kreutzberg
// Email Address: rkreutzb@asu.edu

// protections 
#ifndef StaffMember_H
#define StaffMember_H

using namespace std;

class StaffMember
{
      // protected variables
      protected:
        string firstName;
        string lastName;
        string memberId;
        double pay;
                
      // public functions
      public: 
        StaffMember(string1, string2, string3)
        {
               firstName = string1;
               lastName = string2;
               memberId = string3;
               pay = 0.0;
        }
        
        string getMemberId()
        {      return memberId;   }
        
        virtual void computePay() = 0;
        
        virtual void printInfo()
        {       cout << "\nFirst name:\t\t" << firstName << "\nLast name:\t\t" << lastName << "\nMember ID:\t\t" << memberId << "\nPay:\t\t\t$" << pay << "\n" << endl;      }

};

#endif

Thank you in advance for any help you can provide!!

Okay, I think I made some headway on the StaffMemberParser code. However, now when I compile, I am getting some more errors other than the one I mentioned in my above post (which is still unresolved - help on that please!). Now, the errors I am getting are as follows:

23 StaffMember.h expected `)' before ',' token [NOTE: this is the one from before, just FYI]
17 Assignment7.cpp In static member function `static StaffMember* StaffMemberParser::parseStringToMember(std::string)':
15 StaffMemberParser.h cannot convert `std::string' to `const char*' in initialization

So, as you can see, I am getting errors in three of my files. They are all posted below, including the updated version of StaffMemberParser.h. How can I fix these errors? Thank you for your help!

// 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;
  /***********************************************************************************
  ADD your code here to create a pointer to an object of one of child classes of 
  StaffMember class and add it to the memberList
  ***********************************************************************************/
			break;
		case 'C':   //Compute Pay
  /***********************************************************************************
  ***  ADD your code here to compute the pay for all members the memberList.
  ***********************************************************************************/
			cout << "pay computed\n";
			break;
		case 'D':   //Search for Member
			cout << "Please enter a memberID to search:\n";
			cin >> inputInfo;
			operation = false;
  /***********************************************************************************
  ***  ADD your code here to search a given memberID. If found, set "found" true,
  ***  and set "found" false otherwise.
  ***********************************************************************************/
			if (operation == true)
				cout << "member found\n";
			else
				cout << "member not found\n";
			break;
		case 'L':   //List Members
  /***********************************************************************************
  ***  ADD your code here to print out all member objects. If there is no member,
  ***  print "no member\n"
  ***********************************************************************************/
			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";
}
// StaffMember.h
// Assignment #: 7
// Name:
// Email Address: 

// protections 
#ifndef StaffMember_H
#define StaffMember_H

using namespace std;

class StaffMember
{
      // protected variables
      protected:
        string firstName;
        string lastName;
        string memberId;
        double pay;
                
      // public functions
      public: 
        StaffMember(string1, string2, string3)
        {
               firstName = string1;
               lastName = string2;
               memberId = string3;
               pay = 0.0;
        }
        
        string getMemberId()
        {      return memberId;   }
        
        virtual void computePay() = 0;
        
        virtual void printInfo()
        {       cout << "\nFirst name:\t\t" << firstName << "\nLast name:\t\t" << lastName << "\nMember ID:\t\t" << memberId << "\nPay:\t\t\t$" << pay << "\n" << endl;      }

};

#endif
// StaffMemberParser.h

#include <stdio.h>

// protections 
#ifndef StaffMemberParser_H
#define StaffMemberParser_H

using namespace std;

class StaffMemberParser
{
      static StaffMember * parseStringToMember(string lineToParse)
      {
             const char *ptr = lineToParse;
             char field [100];
             int n;
             
             while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
             {
                  type = field;
                  ptr += n;
                  if ( *ptr != ';' )
                  {
                       break; /* didn't find an expected delimiter, done? */
                  }
                  while ( *ptr == ';' )      
                  { 
                       ++ptr; /* skip the delimiter */    
                  }
             }  
      }
};

#endif

Edited 7 Years Ago by vileoxidation: n/a

StaffMember(string &string1, string &string2, string &string3)
const char *ptr = lineToParse.c_str();

Edited 7 Years Ago by Dave Sinkula: n/a

Dave, thank you so much! That fixed all of my errors. Now I just have to work on getting my code working right! I am still trying to write the StaffMemberParser class, because what it is supposed to do is tell if the user enters a volunteer, full time employee, or hourly employee by reading the first token of the string, and then it is supposed to tokenize the rest of the string into things like first name, last name, and ID number. How do I do that? Do I alter the while loop in some way? How do I tell it to save to the variable firstName for the second token, lastName for the third, and so on?

Here is my StaffMemberParser.h file:

// StaffMemberParser.h

#include <stdio.h>

// protections 
#ifndef StaffMemberParser_H
#define StaffMemberParser_H

using namespace std;

class StaffMemberParser
{
      static StaffMember * parseStringToMember(string lineToParse)
      {
             const char *ptr = lineToParse.c_str();
             char field [100];
             int n;
             string type;
             
             while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
             {
                  type = field;
                  ptr += n;
                  if ( *ptr != '/' )
                  {
                       break; /* didn't find an expected delimiter, done? */
                  }
                  while ( *ptr == '/' )      
                  { 
                       ++ptr; /* skip the delimiter */    
                  }
             }  
      }
};

#endif

Thank you for helping me!!

Edited 7 Years Ago by vileoxidation: n/a

Something along this line?

class StaffMemberParser
{
   static StaffMember * parseStringToMember(string lineToParse)
   {
      const char *ptr = lineToParse.c_str();
      char field [100];
      int n, i = 0;

      while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
      {
         switch ( i++ )
         {
         case 0: /* volunteer/full time/hourly? */ break;
         case 1: firstName = field; break;
         case 2: lastName  = field; break;
         case 3: memberId  = field; break;
         default: break;
         }
         ptr += n;
         if ( *ptr != ';' )
         {
            break; /* didn't find an expected delimiter, done? */
         }
         while ( *ptr == ';' )
         {
            ++ptr; /* skip the delimiter */    
         }
      }  
   }
};

Sort of like that. The problem with that way is that the information entered will vary depending on if the entry is a volunteer or one of the employee types. For instance, for volunteer, there is no pay rate, but for the employees, there is either an hourly rate or a rate and a bonus, depending on the type of employee. Do I still use a switch statement for this?

A switch, an if-tree, some combination: it's your preference.

string type;

      while ( sscanf(ptr, "%31[^/]%n", field, &n) == 1 )
      {
         switch ( i++ )
         {
         case 0: type      = field; break; /* capture type for later use */
         case 1: firstName = field; break;
         case 2: lastName  = field; break;
         case 3: memberId  = field; break;
         case 4:
            if ( type == "volunteer" )
            {
               /* nothing to do (field should be empty so we never get here?) */
            }
            else if ( type == "hourly" )
            {
               /* convert field text into double and store in pay (?) */
            }
            else
            {
               /* ??? */
            }
            break;
         case 5: /* bonuus (?) */ break;
         default: break;
         }
         /* ... */
      }

Have you posted a sample input line?

No, I haven't...here is the example that was provided for me:

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

A real example of this string would be:
Volunteer/Barack/Obama/000001
OR
FullTimeEmployee/George/Bush/200005/400000/50000
OR
HourlyEmployee/Bill/Clinton/000002/25.25/10

Comments
Danke.

Okay, that makes sense. How do I convert the text field to a double for pay and the other numbers? That is the only error I am getting for that function when I compile now.

Here is what I have right now:

// StaffMemberParser.h

#include <stdio.h>

// protections 
#ifndef StaffMemberParser_H
#define StaffMemberParser_H

using namespace std;

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 = field;
                              }
                              else if ( type == "FullTimeEmployee" )
                              {
                                   rate = field;
                              }
                              break;
                         case 5:
                              if ( type == "Volunteer" )
                              {
                                   // nothing to do
                              }
                              else if ( type == "HourlyEmployee" )
                              {
                                   hoursWorked = field;
                              }
                              else if ( type == "FullTimeEmployee" )
                              {
                                   bonus = field;
                              }
                              break;
                         default: break;
                  }
                  ptr += n;
                  if ( *ptr != '/' )
                  {
                       break;  // didn't find an expected delimiter
                  }
                  while ( *ptr == '/' )      
                  { 
                       ++ptr;  // skip the delimiter     
                  }
             }  
      }
};

#endif

Also, I have a question about my main function, called Assignment7.cpp. I am supposed to add to the code that we were given, so that the main function creates a pointer to an object belonging to one of the child classes, and I am also supposed add code so that the computePay function is called for every staff member in the memberList. I am confused about how to do these two things, because I don't know how to tell the code which child class the object is a member of, and I also don't now how to call the computePay function, because I tried memberList.computePay(); and I got an error. Can you help me figure out how to do these two things in my main function?

Here is the code for my main function:

// 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;
  /***********************************************************************************
  ADD your code here to create a pointer to an object of one of child classes of 
  StaffMember class and add it to the memberList
  ***********************************************************************************/
			break;
		case 'C':   //Compute Pay
  /***********************************************************************************
  ***  ADD your code here to compute the pay for all members the memberList.
  ***********************************************************************************/
			memberList.computePay();
            cout << "pay computed\n";
			break;
		case 'D':   //Search for Member
			cout << "Please enter a memberID to search:\n";
			cin >> inputInfo;
			operation = false;
  /***********************************************************************************
  ***  ADD your code here to search a given memberID. If found, set "found" true,
  ***  and set "found" false otherwise.
  ***********************************************************************************/
			if (operation == true)
				cout << "member found\n";
			else
				cout << "member not found\n";
			break;
		case 'L':   //List Members
  /***********************************************************************************
  ***  ADD your code here to print out all member objects. If there is no member,
  ***  print "no member\n"
  ***********************************************************************************/
			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";
}

Okay, that makes sense. How do I convert the text field to a double for pay and the other numbers? That is the only error I am getting for that function when I compile now.

Here is one way:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

The heart of it is the stringstream stuff.

Also, I have a question about my main function, called Assignment7.cpp. I am supposed to add to the code that we were given, so that the main function creates a pointer to an object belonging to one of the child classes, and I am also supposed add code so that the computePay function is called for every staff member in the memberList.

From what you've got, it seems like you might want to parse into temporaries for use with the constructor. Maybe you're supposed to new an object?

I am confused about how to do these two things, because I don't know how to tell the code which child class the object is a member of, and I also don't now how to call the computePay function, because I tried memberList.computePay(); and I got an error. Can you help me figure out how to do these two things in my main function?

I'm playing along at home, but when time allows.

I'm playing along at home, but when time allows.

I totally understand about getting this stuff in when you have time! I have two weeks left to do this assignment, as it is not due till the 21st, but I just like to get an early start on things. No hurry at all on any of my questions, so please don't feel rushed!! I would hate to be a burden on anyone. :-)

Here is one way:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

The heart of it is the stringstream stuff.

Oh, okay, I didn't realize I needed to make a function to do it. I did that, and created one for converting doubles, as well as one for converting ints, so that is all taken care of. Thank you for that reference!

From what you've got, it seems like you might want to parse into temporaries for use with the constructor. Maybe you're supposed to new an object?

I think we are supposed to use a new object...I'm just confused about telling it which child class to call. Do I want to call my StaffMemberParser class and use that to tell what it is?


Also, I am getting an error when I compile still. The error is in my main function, and is as follows:
54 Assignment7.cpp 'class std::vector<StaffMember*, std::allocator<StaffMember*> >' has no member named 'computePay'

However, I have defined computePay in StaffMember, so I am unsure about what this is telling me. Do you need to see some of my code to figure out what this is telling me?

Thank you so much for all of the help, Dave!! I so appreciate it. And again, no rush!! :-D

Okay, I figured that error out. But now I am working on the main function of this program, and am getting another error. What I am trying to do is to create an object of one of the child classes (FullTimeEmployee, HourlyEmployee, or Volunteer) depending on the type the user enters. I have a parser class, called StaffMemberParser, which tokenizes a string into bits, and I think I have to utilize that, but I am unsure about how to use the variables from that class in my main function. Here are the errors I am getting:

45 Assignment7.cpp cannot convert `std::string' to `StaffMember*' in initialization
46 Assignment7.cpp `type' undeclared (first use this function)
48 Assignment7.cpp `Volunteer' undeclared (first use this function)
and so on

and then this error multiple times:
59 Assignment7.cpp jump to case label
45 Assignment7.cpp crosses initialization of `StaffMember*parseStringToMember'


Can someone help me figure this out?

Here is my main function, as well as the parser file:

// 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);
            if ( type == "Volunteer" )
            {
                Volunteer *new_guy = new Volunteer(firstName, lastName, employeeId);
            }
            else if ( type == "HourlyEmployee" )
            {
                HourlyEmployee *hourly = new HourlyEmployee(firstName, lastName, employeeId, rate, hoursWorked);
            }
            else if ( type == "FullTimeEmployee" )
            {
                FullTimeEmployee *fullTime = new FullTimeEmployee(firstName, lastName, employeeId, rate, bonus);
            }
			break;
		default:
			cout << "Unknown action\n";
			break;
		}

	} while (input1 != 'Q' && input1 != 'q'); // stop the loop when Q is read

}
// 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
This article has been dead for over six months. Start a new discussion instead.