arrays of a class

Here is my code:

#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

//Declaration of Date class including data members and member functions.
class Date
       int month;
   int day;
   int year;
   static int days[];
   char *mn;
   char *dy;
   char *yr;
       Date(int m, int d, int y);            //constructor with integer params.
   Date(const char *dt_ptr);             //Constructor with string param.
   void CheckDays(int m, int d, int y);  //check the day of months and years.
   int IsLeapYear(int y);                //check if the year is leap year.
   void PrintDate() const; //print the date with format: 11-09-1997.


//prototype of data member days[]:
int Date::days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

      month = 0;
      day = 0;
      year = 0;

//prototype of constructor with integers parameters:
Date::Date(int x, int y, int z)
      month = x;
   day = y;
   year = z;
   CheckDays(month, day, year);      //Validate the date(s).

//prototype of constructor with string parameters:
Date::Date(const char *dt_ptr)
   char * dt = new char [strlen(dt_ptr) + 1];//new dynamic memory allocation.
   strcpy(dt, dt_ptr);                       //copy to a local pointer.

   //Check if the string with format "MMM DD,YYYY"
   if isalpha(*dt)
      mn = strtok(dt, " ,");         // "MMM"
      dy = strtok(NULL, " ,");       // "DD"
         yr = strtok(NULL, " ,");       // "YYYY"

      for (char *m = mn; *m != '\0'; m++)
            *m = (char) tolower(*m);        //Generalize all characters.

      if (strcmp(mn, "jan") == 0)
            strcpy(mn, "1");
         else if (strcmp(mn, "feb") == 0)
               strcpy(mn, "2");
         else if (strcmp(mn, "mar") == 0)
               strcpy(mn, "3");
         else if (strcmp(mn, "apr") == 0)
               strcpy(mn, "4");
         else if (strcmp(mn, "may") == 0)
               strcpy(mn, "5");
         else if (strcmp(mn, "jun") == 0)
                  strcpy(mn, "6");
         else if (strcmp(mn, "jul") == 0)
               strcpy(mn, "7");
      else if (strcmp(mn, "aug") == 0)
               strcpy(mn, "8");
         else if (strcmp(mn, "sep") == 0)
               strcpy(mn, "9");
         else if (strcmp(mn, "oct") == 0)
               strcpy(mn, "10");
         else if (strcmp(mn, "nov") == 0)
               strcpy(mn, "11");
         else if (strcmp(mn, "dec") == 0)
            strcpy(mn, "12");
               cout << "Program error!";

   //Check if the string with format: "MM/DD/YYYY":
   else if isdigit(*dt)
      mn = strtok(dt, " /");            // "MM"
         dy = strtok(NULL, " /");          // "DD"
         yr = strtok(NULL, " /");          // "YYYY"

   //Otherwise, print out error msg:
         cout << "Program error!";

   //convert all the string to integer to make validation easier.
   month = atoi(mn);
   day = atoi(dy);
   year = atoi(yr);

   delete [] dt;                   //delete the dynamic memory allocation.
   CheckDays(month, day, year);    //validate the date(s).

//prototype of validation function:
void  Date::CheckDays(int m, int d, int y)
   if (m >= 1 && m <= 12) month = m;
   else month = 0;
   if (y >=1900 && y <= 2100) year = y;
   else year = 0;
   //month = (m >= 1 && m <=12) ? m : 1;           //validate the months.
   //year = (y >=1900 && y <= 2100) ? y: 1900; //validate the years.
   //validate the days:
   if (month == 2 && IsLeapYear(year)== 0)
   {      if (d > 28) cout << "Problem occurs on the following dates: " ;
      else day = d;
      if (d >= 1 && d <= days[month]) day = d;
         //day = (d >= 1 && d <= days[month]) ? d : 1;

   if (d >= 1 && d <= days[month]) day = d;

//prototype of function to check if it is leap year:
int  Date::IsLeapYear(int y)
      if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
         return 1;
         return 0;

//prototype of function PrintDate():
void Date::PrintDate() const
      cout << month << '-'        << day << '-'  << year;

//***Employee class**

class Employee
       Date HireDate;
   Date BirthDate;
   int SSN;
   //float HourlyRate;
   //float HoursWorked;
   //float TotalPay();
       void print() const;
   Employee(int, int, int, int, int, int, int );

                   :BirthDate(), HireDate()
      SSN = 0;
   //HourlyRate = 0.00;
   //HoursWorked = 0.00;

Employee::Employee(int bmonth, int bday, int byear,
                                     int hmonth, int hday, int hyear, int s)
                   :BirthDate(bmonth, bday, byear),
                    HireDate(hmonth, hday, hyear)
      SSN = s;
   //HourlyRate = h_r;
   //HoursWorked = h_w;

void Employee::print() const
      cout << "Employee: " << SSN;
   cout << endl;
//main function:
int main(void)
   int n;
   int i;
   int b_month;
   int b_day;
   int b_year;
   int h_month;
   int h_day;
   int h_year;
   int ss;
   int hr;
   int hs;
   cout << "Please enter how many employees you want to process:" ;
   cin >> n;
   Employee * p = NULL;
   p = new Employee[n];
//is the code above correctly create a array of class //Employee? If n = 2, I should have enough memory location //for 3 employee right?
   for (i = 0; i < n; i++){
         cout << "Employee " << i << ":";
      cout << "Month of birth:";
      cin >> b_month;
      cout << "Day of birth:";
      cin >> b_day;
      cout << "Year of birth:";
      cin >> b_year;
      cout << "Month of hiring:";
      cin >> h_month;
      cout << "Day of hiring:";
      cin >> h_day;
      cout << "Year of hiring:";
      cin >> h_year;
      cout << "Social Security Number:";
      cin >> ss;
      cout << "Hourly rate for this employee:";
      cin >> hr;
      cout << "How many hours did he work the past week:";
      cin >> hs;

      //Employee f(b_month, b_day, b_year, h_month, h_day, h_year, ss);
   Employee e(7, 24, 1993, 3, 33, 1949, 121789174);
   Employee f(b_month, b_day, b_year, h_month, h_day, h_year, ss);
   cout << "Hello\n";


Here is what I suppose to do:
Create an array of class Employee. prompt user to enter how many employee I want to process. and put them into that array. then print them together. and sort them by ssn.

Right now, my code can only prompt user and create an array the class employee. and print them one at a time.

How can I store the information into the array of employee and the print them all out at one time?
I also need a hint on how to sort them?

Thank you
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Answer coming.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Yes the way you create the array of employees is correct.  I would just make one change for optimization purposes (doesn't effect the outcome)  I would do

Employee *p = new Employee[n];

instead of

Employee *p = NULL;
p = new Employee[n];

There is no need to set p to NULL and them immediately to something alse.

To set the information in the array you will use a loop of some sort (a "while" loop or a "for" loop).  You will use a pointer to keep track of the item that needs to be entered.  It will look a little bit like this.

Employee *CurEmp = p;

for (int i=0; i<n; +=i)
   cin >> *CurEmp;

This assumes that you've created a >> operator to get an employee from a stream.  If not, substitute whatever data entry mechanaism  you want.  This could also be optimized to

for (int i=0; i<n; +=i)
   cin >> *CurEmp++;

To sort the data in the array you can use the quicksort procedure provided in the standard library.  The procedure is called qsort().

There are two parts to using qsort().  First you need to write a procedure that will compare two of items and indicate which is larger.  The qsort() procedure will call this procedure whenever it needs to compare two items.

Let mes send this an continue.

The comparison routine will be called with pointers to two items in the array being sorted.  Unfortunately the pointers will be void * pointers and must be cast to employee * pointers.  Like

void *E1;
const Employee *Emp1 = (const Employee *) E1;

The return value of the comparison routine follows the same conventions as the memcmp() procedure.  (This is convenient because, 99% of the time the comparison routine just calls memcmp().)  Since your sort key (social security number) is contained in a single member, this is not necessary.  You can simple compare by subtractng the second item's SSN from the first item's SSN.  The comparison routine will look something like this

int CmpEmp(const void *E1,const void *E2)
   const Employee *Emp1 = (const Employee *) E1;
   const Employee *Emp2 = (const Employee *) E2;

   return Emp1->SS - Emp2->SS;

Then the qsort() call just needs to specify the location if the array, the size of the items to sort and a pointer to the comparison procedure.


p points to start of array.  n is the number of items in the array.

Hope this helps.
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

ny971181Author Commented:
looks very good.
I will be back.

ny971181Author Commented:
I don't understand what this can do for me:
Employee * CurEmp = p;

for (int i = 0; j < n; j++)
 cin >> *CurEmp;
first, I don't have >> operator overloading function setup as you can see in my code. second: what I understand is CurEmp is a pointer pointing to another pointer which points to a type Employee. if the array has 3 employees, CurEmp++ will make p point to the next employee, or the CurEmp directly point to next employee?
Those are what I don't understand from your question, could you explain more?
And what I want is I store all parameters into the class Employee array for each instance. then print them all out at one time. But my code can only do this: I enter 1st and 2nd employee, my program can only print the latest one which erace the previous one. so I only can print one employee. Can you show me how to fix it?

Thank you
Givin the code

Employee *CurEmp = p;

you say "CurEmp is a pointer pointing to another pointer which
points to a type Employee", but that is wrong.  That would be

Employee **CurEmp = p;

The declaration

Employee *CurEmp = p;

means that CurEmp points to an Employee.  So you can use *CurEmp (or CurEmp->) just like an Employee.


The for loop

for (int i = 0; i < n; ++i)
   // Initialize an emplyee using *CurEmp,
   // for example
   // cin >> *CurEmp;

shows you how to "get hold" of each employee in the array to initialize it.  I'm not sure what you need to do to initialize an employee, so I didn't put anything in.  You probbably need to add a function or two to employee to allow it to be initialized.  For example you mught want to add one to set the social security number.  Then in the loop you would have.

Employee *CurEmp = p;

for (int i = 0; i < n; ++i)
   int SSN;

   cout << "Please enter SSN for Employee Number: " << i+1;
   cin >> SSN;

You might also have procedures for setting bithdate, pay rate, etc.


Printing is similar.  Say you have a memberprocedure for printing called Print(),

Employee *CurEmp = p;

for (int i = 0; i < n; ++i)


I missed one of your questions in there.

p = new Employee[n];
If n = 2, I should have enough memory location for 3 employees right?

No.  Only two employees.  When you declare an array, the number
in the brackets ([]) is the number of items the array can hold.  When you index an array to get at an item in it, then the number in the brackets is an index and it can be from 0 to one less than the number of items in the array.  

If you declare an array with 3 items (int A[3]) the valid indexes are 0,1, and 2 (A[0], A[1], and A[2]).  Iy you declare an array with n items.  The valid indexes are 0 to (n-1).


Note your for loop in your comment has both i's and j's.  Probably not what you meant.  Also, whenever it doesn't matter to your code, use


rather than


For example, use ++i instead of i++.  The pre-increment version may optimize better than the post-increment.  Same with decrement.
ny971181Author Commented:
I am very satisfied with your answer. but probably I will have some follow up question. when I finish my program, I will grade you:)

ny971181Author Commented:
when you declare Employee *p = new Employee[n];
isn't is p a pointer also?
So you declare Employee *CurEmp  =p;
CurEmp should be a pointer point to p which is a type Employee when p is still pointing to the array. right?
sorry, but it is confusing.

I'm having trouble understanding your question.  But I'll take a guess at what your are asking.  (There is a common confussion with pointers and arrays).

This is a little tough to explain.  C (and C++) are a little unusual in how they handle arrays.  In C arrays are only slightly different than pointers.  No other language that I know of (except, in a sense, assembly language) does this.  Let me see if I can explain.

When you declare an array, the name you give the array is treated like a  pointer to the first element in an array.  Usually only a pointer value can be assigned to a pointer variable, so for example

int  I;
int *IPtr1;
int *IPtr2;

IPtr1 = &I;
IPtr2 = IPtr1;

Both of the assignments above assign a integer pointer value to an integer pointer variable.  That is how you would expect to use pointers.  But there is another way.  An array's name is considered a pointer to the first item in the array, so you can do

int  IArray[10];
int *IPtr1;

IPtr1 = IArray;

That's a little unusual compared to other languages.  Other languages would make you do

IPtr1 = &IArray[0];

which you can do in C, but you don't have to.

Now you probably know you can add and subtract from a pointer to get a pointer to an item that is before or after the one pointer to.   (i.e. IPtr1+1 points to the integer after the one IPtr points to)  But you can also do that with arrays.  

IArray + 5;

both access the 6th element in an array.

You probably know that you can subscript an array (using []) to get an element.  But you can also do that with a pointer.

The following code shows 4 ways that the value in the 3rd element of an array can be accessed.

int I;
int IArray[10];
int IPtr = IArray;

I = IArray[2]; // Typical.
I = IArray+2;  // Unusual.
I = IPtr + 2;  // Typical.
I = IPtr[2];   // Unusual.

Hope this helps.
ny971181Author Commented:
Thank you very much!

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.