Solved

arrays of a class

Posted on 1997-12-04
10
266 Views
Last Modified: 2013-12-14
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
{
 private:
       int month;
   int day;
   int year;
   static int days[];
   char *mn;
   char *dy;
   char *yr;
 public:
       Date();
       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.
   //~Date();
};

//------------------------------------------------------------------------------

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

Date::Date()
{
      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");
         else
               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:
   else
         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;
   }
   else
      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;
   else
         return 0;
}

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

//-------------------
//***Employee class**

class Employee
{
 private:
       Date HireDate;
   Date BirthDate;
   int SSN;
   //float HourlyRate;
   //float HoursWorked;
   //float TotalPay();
 public:
       void print() const;
   Employee();
   Employee(int, int, int, int, int, int, int );
};

Employee::Employee()
                   :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;
   HireDate.PrintDate();
   BirthDate.PrintDate();
   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];
//
//QUESTION 1:
//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);
      //f.print();
   }
   Employee e(7, 24, 1993, 3, 33, 1949, 121789174);
   Employee f(b_month, b_day, b_year, h_month, h_day, h_year, ss);
   //f.print();
   cout << "Hello\n";
   e.print();

}

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
0
Comment
Question by:ny971181
  • 5
  • 5
10 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 1174803
Answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1174804
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;
   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.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1174805
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.

qsort(p,n,sizeof(Employee),CmpEmp);

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

Hope this helps.
0
 
LVL 1

Author Comment

by:ny971181
ID: 1174806
looks very good.
I will be back.


0
 
LVL 1

Author Comment

by:ny971181
ID: 1174807
oops.
I don't understand what this can do for me:
Employee * CurEmp = p;

for (int i = 0; j < n; j++)
{
 cin >> *CurEmp;
 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
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 22

Expert Comment

by:nietod
ID: 1174808
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;
   ++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;
   CurEmp->SetSSN(SSN);
   ++CurEmp;
}

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)
{
   CurEmp->Print();
   ++CurEmp;
}

**************************

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

++something

rather than

something++

For example, use ++i instead of i++.  The pre-increment version may optimize better than the post-increment.  Same with decrement.
0
 
LVL 1

Author Comment

by:ny971181
ID: 1174809
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:)
Thanks

0
 
LVL 1

Author Comment

by:ny971181
ID: 1174810
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.


0
 
LVL 22

Expert Comment

by:nietod
ID: 1174811
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];
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.
0
 
LVL 1

Author Comment

by:ny971181
ID: 1174812
Thank you very much!


0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now