Hey folks - i am working on an assignment for school and would like some input if possible.

I am trying to declare a class object in the form of an array so that i can read info from file and then manipulate the data.

I need 3 seperate c++ files for this assignment. One is a header file, which contains the class definition etc. The other cpp file contains the class methods, while the third contains the main part of the program. Both the main cpp file and the methods cpp file have the header file included

#include "Employee.h"

Within the main.cpp file i am trying to do this:

#include "Employee.h"
#include <iostream>

using namespace std;

int buildEmployeeList(Employee []);

int main()
{
int array_size = 0;
// Declare Employee object array for employees
Employee employee_list[100];

array_size = buildEmployeeList(employee_list); //Builds the employee array object
   
    system("PAUSE");
    return 0;
}

int buildEmployeeList(Employee employee_list[])
{
    //DOES STUFF
    int count = 1;
    return count; 
}

I get a linker error with the above code. My header file is:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include <fstream>
#include <istream>

using namespace std;

class Employee
   {
   private:
           char firstName[11];
           char lastName[16];
           char department[16];
           double salary;
   public:
          Employee();
          char *getDepartment();
          double getSalary();
          void print();
          
   };

#endif /* EMPLOYEE_H */

And my method cpp file is:

#include "Employee.h"
#include <iostream>

/****************************************************************
   FUNCTION:   Employee:Employee()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      This is the class Employee constructor
****************************************************************/
Employee::Employee()
{    
     firstName[0] = '\0';   //Sets null char to firstName                                        
     lastName[0] = '\0';    //Sets null char to lastName
     salary = 0;            //Sets salary to 0
}

/****************************************************************
   FUNCTION:   Employee::getDepartment()
   ARGUMENTS:  none
   RETURNS:    Department name
   NOTES:      Returns the name of the department for the individual
****************************************************************/
char * Employee::getDepartment()
{
     return department;
}

/****************************************************************
   FUNCTION:   Employee::getSalary()
   ARGUMENTS:  none
   RETURNS:    Salary amount
   NOTES:      Returns the salary for an individual
****************************************************************/
double Employee::getSalary()
{
       return salary;
}

/****************************************************************
   FUNCTION:   Employee::print()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      Prints the values of the data members 
****************************************************************/
void Employee::print()
{
     cout << "Name ---- Department ---- Salary";
}

int main()
{
    return 0;
}

So why cant i declare my Employee employee_list[100] in the main.cpp file? Am i not referencing the Class Employee correctly? Sorry if my code is awful, i havent coded anything in 3 months and forgot half of it!

Please any answers or questions to help me would be awesome. Just point me in the right direction, throw me a link so i can learn, anything would be great.

>>I get a linker error with the above code
What is the error message ?

>>So why cant i declare my Employee employee_list[100] in the main.cpp file?
I thought you said you are getting a link error? link errors will not produce this error, but a compile error will. What is the exact compile error?

[Linker error] undefined reference to `Employee::Employee()'
ld returned 1 exit status

Is the exact error i get. I am using dev c++.

The error is a 'linker error' so im assuming the files arent compiling correctly or seeing each other or something? What does this error really mean?

Thanks for the reply!

Everything compiled ok, that error message just means it could not find the class constructor. Make sure method.cpp is part of the dev-cpp project.

One error is that the project has two main() functions. you need to delete one of them.

You were right. The reason it wouldnt see the method.cpp file is that i was trying to compile the program within dev c++ but it wasnt set up as a project. Im unsure how to do this. Is it really as simple as starting a project and loading the files up into dev c++?

The way i have to compile the program is through UNIX. I created my own makefile and uploaded the 3 files, method.cpp main.cpp and employee.h onto the UNIX system, then called make , then it compiled just fine.

*** i was able to get Dev C++ to compile my program / project just fine. Thanks again for all the great help Dragon. If anything else comes up - ill post here :) thanks again

Another quick question. Under my class (within header file employee.h) i have firstName, lastName, department, and salary. If i am working from my main.cpp how can i access the private section of this class. I understand the only way to do this would be to be within one of the Classes methods correct? Within the main.cpp i am trying this:

int buildEmployeeList(Employee employee_list[])
{
  int count = 0;
  
  ifstream inFile;
  inFile.open("employees1", ios::binary);
  if (inFile.fail())
    {
    cout << "Unable to open employees1 file\n";
    exit(1);
    }
   inFile >> employee_list[count].firstName;
   while (!inFile.eof())
     {
     inFile >> employee_list[count].lastName;
     inFile >> employee_list[count].department;
     count++;
     inFile >> employee_list[count].firstName;
     }
inFile.close();
return count;

}

I obviously get errors telling me these members are private! Duh!

(both my employee.cpp and employee.h files i posted above are unchanged from before)

I thought if i am working from an array type from the class created - it should have access aswell? no? Confused with permissions from outside of class then! Any way around this. Will keep working - has to be a logical way !Thanks in advance for suggestions or links for help with classes! (basic stuff please!)

The whole idea of private data members is to prevent code outside the class from directly accessing them. Two reasons:
1. To hide the actual method of storing. Does it matter to main.cpp whether you use a char array based string or a string class item to hold the names? Should it matter to main.cpp if you later change how they are stored? No, not if you've constructed the class methods correctly.

2. To provide a means of validating the inputs before actually storing to the data member. Consider a date class. Would it make sense to allow a user of the class to directly set the day of month to 35?

So, you generally create public class methods that will allow the user program to pass in inputs, and the class method will then store that value to the private data member, if appropriate.

To solve your current programming problem, you probably should create get( ) and set( ) methods for each data element. Then in main read into temporary variables, and pass those values to the corresponding set( ) method.
Val

THanks for the help once again Val. I got a reply from my TA in my c++ class about my question also. With both your help i figured out a way to solve my problem. At least i thought so --- here is what i did.

int buildEmployeeList(Employee employee_list[])
{
  int count = 0;
  //char first[16] = "\0", last[16] = "\0", depart[11] ="\0";
  ifstream inFile;
  inFile.open("employees1", ios::binary);
  if (inFile.fail())
    {
    cout << "Unable to open employees1 file\n";
    exit(1);
    }
   inFile.read((char *)&employee_list[count], sizeof(Employee));
   while (!inFile.eof())
     {
         count++;
     inFile.read((char *)&employee_list[count], sizeof(Employee));

     }
inFile.close();
for (int i = 0; i < 15; i++)

cout << "Department: " << employee_list[i].getDepartment()<< "Salary: " << employee_list[i].getSalary() << endl;
return count;

}

This is it working - it will print out my Department, and the salary, and looking at a example print out - it all lines up with correct department and figures. BUT ... how would i access the names still? I cant do:

employee_list[i].Employee::Employee(); (the constructor contains the first name, last name, and salary 

Employee::Employee()
{    
     firstName[0] = '\0';   //Sets null char to firstName                                        
     lastName[0] = '\0';    //Sets null char to lastName
     salary = 0;            //Sets salary to 0
}

This is on my methods.cpp file. Im getting the hang of it (sort of, but would like confirmation that im on the right path - the answers just there ... i just can see it in the code...!)

Thanks once again in advance -

You already have getDepartment and getSalary accessor functions. Write accessor functions getLastName and getFirstName. They'll be almost identical to getDepartment.

class Employee
   {
   private:
           char firstName[11];
           char lastName[16];
           char department[16];
           double salary;
   public:
          Employee();
          char *getDepartment();

          char* getLastName ();   // add this function.
          char* getFirstName ();  // add this function.


          double getSalary();
          void print();
          
   };

If in fact that infile.read( ) statement is working, it depends on your data file having exactly the right number of characters for each field (fname, lname, dept, oops, how's it going to read in the salary of type double?)

And you are still violating the premise that the data members are private, only to be directly accessed by class methods.

As I mentioned before, you should have methods that get and set each (or combinations of ) data element.

void Employee::setDepartment(  char * dept )
{
     strcpy( department, dept );
}

void Employee::setFirstname( char * fname )
{
     strcpy ( firstName, fname );
}

Here is where you build in protection. What if the user provided a first name that was 15 characters long? Copying that in full would then overwrite part of the last name, or run outside the bounds of the object's storage. Bad in either case. A better implementation would check the length of input and only store the portion that fits.

void Employee::setFirstname( char * fname )
{
     if( strlen( fname ) < 10 )
         strcpy ( firstName, fname );
     else
     {
         strncpy( firstName, fname, 10 );
         firstName[10] = '\0';
     }
}

Now in main.cpp, you have:

char fname[100] = "";   //big enough for any unreasonable input
      char lname[100] = "";   //etc.

      infile >> fname;   //or use getline if each data item on separate line in file
      employeeList[n].setFirstname( fname );
      //do the same read and set action for the other data elements

The reasons i chose such small numbers (sorry for not explaining earlier) is that that are the numbers given per the assignment (obviously the professor knew no names were going to be over 15 char long (plus null so 16 - right)? so thats why i dont believe i should use protection for longer strings. If i were given a random list of names i understand i would have to take different names into consideration!

I will create getFirstName() and getLastName methods - should work the same - great idea, thank you so much -

Will get back to you if something else comes up.

Hey folks. I have been able to sort out a large portion of this myself (wow i think i might actually be understand the basic stuff at last) and now have come across another problem.

#include "Employee.h"
#include <iostream>

using namespace std;
int const LIST_SIZE = 100;
int buildEmployeeList(Employee []);
void processTransactions(Employee [], int);
void listByDepartment(Employee [], int);
void sortByDepartment(Employee [], int);

int main()
{
int numEmployees;
// Declare Employee object array for employees
Employee employee_list[LIST_SIZE];

//Builds the employee array object
numEmployees = buildEmployeeList(employee_list); 

//Process Transactions
processTransactions(employee_list, numEmployees); 

return 0;
    
}

/*
FUNCTION INFORMATION
***
***
*/
int buildEmployeeList(Employee employee_list[])
{
  int count = 0;
  //char first[16] = "\0", last[16] = "\0", depart[11] ="\0";
  ifstream inFile;
  inFile.open("employees1", ios::binary);
  if (inFile.fail())
    {
    cout << "Unable to open employees1 file\n";
    exit(1);
    }
   inFile.read((char *)&employee_list[count], sizeof(Employee));
   while (!inFile.eof())
     {
     count++;
     inFile.read((char *)&employee_list[count], sizeof(Employee));
     }
inFile.close();

cout << "Below is printed using print() method in Employee.cpp" << endl;
for (int i = 0; i < 2; i++)
{
employee_list[i].print();
}
cout << count;

return count;

}
/*
FUNCTION INFORMATION
***
***
*/
void processTransactions(Employee employee_list [], int numEmployees)
{
int transType;
ifstream inFile;
inFile.open("trans1.txt");
if (inFile.fail()) 
  {
  cout << "open for trans1.txt failed";
  // exit the program
  exit(1);
  } 
inFile >> transType;
while (!inFile.eof())
      {
      /*SWITCH COMMENTED OUT
	 switch ( transType ) {
              case 1:
                   cout << "trans type = 1" << endl;
                   break;
              case 2:
                   cout << "trans type = 2" << endl;
                   break;
              default:
		   cout << "in default case" << endl;
	END COMMENT OUT SWITCH
	*/
        if (transType == 1)
             {
	     cout << "trans type = 1";
             listByDepartment(employee_list, numEmployees);
	     }	
        if (transType == 2)
	     {
             cout << "trans type = 2";       
             }
	inFile >> transType;       
      }
inFile.close();
}

/*
NEED FUNCTION HEADER INFORMATION


*/
void listByDepartment(Employee employee_list[], int numEmployees)
{
cout << "Listed by department" << endl;
sortByDepartment(employee_list, numEmployees);
}

/*
NEED FUNCTION HEADER INFORMATION


*/
[B]void sortByDepartment(Employee employee_list[], int numEmployees)
{
  int i, j;
  int min;
  char temp[16];
  temp[0] = '\0';

  for (i = 0; i < numEmployees - 1; i++)
  {
    min = i;
    for (j = i + 1; j < numEmployees; j++)
    {
      if (employee_list[j].getDepartment() < employee_list[min].getDepartment())
        min = j;
    }
    temp = employee_list[i].getDepartment();
    employee_list[i].getDepartment() = employee_list[min].getDepartment();
    employee_list[min].getDepartment() = temp;
  }

}[/B]

My problem occurs int he bold section, but i wanted to give you the rest, in case something was wrong elsewhere that has to do with this function.

The idea of thsi bold section is to take the values of the employee_list class, the department value, and then sort by selection(have to use this per assignment). But with me using character arrays, how can i set the temp value to work? I tried initializing it just like i did with the department character array - but still get an error. Also there seems to be somethign wrong with these parts:

employee_list[min].getDepartment();

So basically anything containing the [min] part - am i not correctly setting this variable?

Any help on this would be awesome. I will edit the FIRST post that i listed al three files, so that you can see UPDATED employee.h and employee.cpp files...

Thanks in advance

employee.cpp file

#include "Employee.h"
#include <iostream>

/****************************************************************
   FUNCTION:   Employee:Employee()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      This is the class Employee constructor
****************************************************************/
Employee::Employee()
{    
     firstName[0] = '\0';   //Sets null char to firstName                                        
     lastName[0] = '\0';    //Sets null char to lastName
     salary = 0;            //Sets salary to 0
}

/****************************************************************
   FUNCTION:   Employee::getDepartment()
   ARGUMENTS:  none
   RETURNS:    Department name
   NOTES:      Returns the name of the department for the individual
****************************************************************/
char * Employee::getDepartment()
{
     return department;
}

/****************************************************************
   FUNCTION:   Employee::getSalary()
   ARGUMENTS:  none
   RETURNS:    Salary amount
   NOTES:      Returns the salary for an individual
****************************************************************/
double Employee::getSalary()
{
       return salary;
}

/****************************************************************
   FUNCTION:   Employee::print()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      Prints the values of the data members 
****************************************************************/
void Employee::print()
{
     cout << "Name: " << lastName << ", " << firstName << "  Department: "             
          << getDepartment() << "    Salary: " << getSalary() << endl;
}

header file

#include "Employee.h"
#include <iostream>

/****************************************************************
   FUNCTION:   Employee:Employee()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      This is the class Employee constructor
****************************************************************/
Employee::Employee()
{    
     firstName[0] = '\0';   //Sets null char to firstName                                        
     lastName[0] = '\0';    //Sets null char to lastName
     salary = 0;            //Sets salary to 0
}

/****************************************************************
   FUNCTION:   Employee::getDepartment()
   ARGUMENTS:  none
   RETURNS:    Department name
   NOTES:      Returns the name of the department for the individual
****************************************************************/
char * Employee::getDepartment()
{
     return department;
}

/****************************************************************
   FUNCTION:   Employee::getSalary()
   ARGUMENTS:  none
   RETURNS:    Salary amount
   NOTES:      Returns the salary for an individual
****************************************************************/
double Employee::getSalary()
{
       return salary;
}

/****************************************************************
   FUNCTION:   Employee::print()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      Prints the values of the data members 
****************************************************************/
void Employee::print()
{
     cout << "Name: " << lastName << ", " << firstName << "  Department: "             
          << getDepartment() << "    Salary: " << getSalary() << endl;
}

thanks guys

Two problems in your sort.

a - what are you comparing? getDepartment( ) returns a char *, which is an address. Does it make sense to compare addresses? Since the department is allocated a char array, I presume you put one or more words in the field. In that case, you must compare with one of the string comparison functions (strcmp( ) et al).

b - your swap is using getDepartment( ) which may be ok, if you used it right. Since the returned value is pointing to a string, again use string functions, such as strcpy( ) to copy the full strings. Also, you must exchange all the other data fields in the same three way move, otherwise you're just changing the departments that people work in. Simpler in the long run, and part of a good class definition, is to create a copy constructor so you can simply assign class objects in whole.

THanks for the help again. I sorted out my strcpy() problem before i saw this after realizing my own mistake... cant use = to copy strings etc. ... whoops.

I changed that function to look like this:

void sortByDepartment(Employee employee_list[], int numEmployees)
{
  int i, j;
  int min;
  char temp[16];
  temp[0] = '\0';

  for (i = 0; i < numEmployees - 1; i++)
  {
    min = i;
    for (j = i + 1; j < numEmployees; j++)
    {
      if (strcmp(employee_list[j].getDepartment(), employee_list[min].getDepartment()) != 0)
        min = j;
    }
[B]    strcpy(temp, employee_list[i].getDepartment());
    strcpy(employee_list[i].getDepartment(), employee_list[min].getDepartment());
    strcpy(employee_list[min].getDepartment(), temp);[/B]
    employee_list[i].print();
  }

}

This seems to work, in terms of compiling anyway. But i agree with you that i need to switch the entire data field for the employee, because as used above, it obviously just switches the department etc they are in as you said.

Without being able to access the names (first, last, salary) that is contained in the constructor, how else could this be done. I don't see it being possible, without creating (like i had done previously, 2 more get****() methods that get the first name and last name.... this though, is a last resort as my TA says it does NOT need to be done this way! UGH

Any ideas? As always ill keep working - and will post anything i figure out while others try helping!

Thanks again in advance as always

Well, I was a bit overzealous in recommending you implement a copy constructor. For your class, the data members are all simple, so you can simply copy one instance of an employee to another as in:

Employee temp;

temp = employee_list[i];
employee_list[i] = employee_list[min];
employee_list[min] = temp;

If you had used pointers to dynamically allocated memory for the data members, this would not work as desired, you would have to copy member by member or write an assignment operator member function.

commented: great comments and help as always +3

I got this all working really just fine. The assignment is finished. The problem i was having was fixed. My next assignment, i have to add 2 other files to this project. I am adding a another .cpp, and another header file that contains another class definition.

I wrote out the files and am getting an error that i can't seem to explain. The error occurs on this line:

[B]Name Employee::getName()[/B]
{
     return name;
}

The error is:
26 C:\Users\Tony\Documents\School - SP 2008\CSCI 241\assign2\Employee.cpp `Name' does not name a type
The name i use here should, i THINK, be referring to this:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include "Employee.h"
#include <fstream>
#include <istream>
#include <iomanip>

using namespace std;

class Name
   {
   private:
           char firstName[11];
           char lastName[16];
           
   public:
          Name();
          char *getFirstName();
          double *getLastName();
          void print();
          
   };

#endif /* EMPLOYEE_H */

If you need any other parts of my code please let me know. Thanks again - i just didn't want to post 5 files (800+ lines of code)...lol

So it should be refering to this class defintion within Name.h header file. I included a #include for the header file in the .cpp file that the method is coded in....

Could someone explain as to why i am getting this error, i have tried changing the name of the function etc...no luck. Any ideas?

Thanks in advance

The file you posted above looks like it would "Employee.h", based on the #infndef. But it also includes "Employee.h" - so which is it?

In the Employee class, do you correctly have a Name member "name"?
~~~~~~
From the bit you've give, I'd expect you have Name class, in "Name.h" and "Name.cpp". The "Employee.h" should include "Name.h", since the relationship is that an employee "has a" name.

That help?

You, as always, were 100% correct. In my effort to just cut and paste half my first assignment into a new project i neglected to change the header guards for name.h. I corrected this and got the code compiling and running as expected. After working more - and more - on this project i have come across another problem (don't i always?). I seem to be confused when trying to implement the 'insertion sort' algorithm. I will post the function i am trying to use - and will try to add any other snippets of code that i think you may need - if you need or think i am missing something, post and ill get it here.

here is the function:

void sortByName(Employee employee_list[], int numEmployees)
{
  int i, j, index;
  Employee temp;

  for (i=1; i < numEmployees; i++)
  {
[B]    strcpy(temp, employee_list[i].getName());[/B]
    j = i;
    while ((j > 0) && greaterThan(employee_list[j-1].getName(), temp.getName()))
    {
[B]      strcpy(employee_list[j], employee_list[j-1]);[/B]
      j = j - 1;
    }
   [B] strcpy(employee_list[j], temp);[/B]
  }
}

As i can hope you can see - i am ATTEMPTING to sort a list of employees by name - i get errors on the bold lines - i understand the error - but i can't think of another way around what i coded above...

The class passed looks like:

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include "Name.h"
#include <fstream>
#include <istream>
#include <iomanip>

using namespace std;

class Employee
   {
   private:
           //NAME (OBJECT GOES HERE);
           Name name1;
           char ssNumber[10];
           char department[16];
           double salary;
           
   public:
          Employee();
          Name getName();
          char *getSSN();
          void setDepartment(char *);
          void setSalary(double);
          char *getDepartment();
          double getSalary();
          void print();
          
   };

#endif /* EMPLOYEE_H */

This is all the code you should need - for now - the call of the greaterThan() function is a whole other can of worms that i wish to work with until i cant stand it any longer and come crawling back here....

So if possible - could someone explain as to what these errors mean, and what ideas do you have to get around this?

errors:
212 C:\Users\Tony\Documents\School - SP 2008\CSCI 241\assign2\assign2.cpp cannot convert `Name' to `char*' for argument `1' to `char* strcpy(char*, const char*)'
2nd bold part - exact same error
3rd bold part - exact same error

Any ideas? Thanks again guys.

Why are you using strcpy( ) to copy whole employee objects? Just do the assignment.


Assuming your greaterThan( ) function works correctly, and you've not changed any of the other class objects, how about:

void sortByName(Employee employee_list[], int numEmployees)
{
  int i, j, index;
  Employee temp;

  for (i=1; i < numEmployees; i++)
  {
    temp = employee_list[i];
    j = i;
    while ((j > 0) && greaterThan(employee_list[j-1].getName(), temp.getName()))
    {
      employee_list[j] =  employee_list[j-1];
      j = j - 1;
    }
    employee_list[j] = temp;
  }
}

Ha! I noticed that too. I should have copied my previous example ... duh. By doing the above, it seems to work - well at least compile. With the idea i would like to print out the data after sorting the list - i attempted this:

void sortByName(Employee employee_list[], int numEmployees)
{
  int i, j;
  Employee temp;

  for (i=1; i < numEmployees; i++)
  {
    temp = employee_list[i];
    j = i;
    while ((j > 0) && greaterThan(employee_list[j-1].getName(), temp.getName()))
    {
      employee_list[j] = employee_list[j-1];
      j = j - 1;
    }
    employee_list[j] = temp;
[B]   temp[number].print();[/B]
  }
  }

The .print() points to this method:

void Employee::print()
{
     Name employee_name;
     cout << "\nName: ";
     name1.print();
     cout << "SSN:  " << ssNumber << endl;
     cout << "Department: " << department << endl;
     cout << "Salary: $" << setprecision(2) << fixed << salary << endl; 
}

Which also points to another, to get the first, last names of the employee - this works fine for my previous sort by department - but when i try printing for sort by name i get this list:

Sorted by Employee Name **************************

Name: Sampson, Grace
SSN: 555326363
Department: Accounting
Salary: $45727.00

Name: Sampson, Grace
SSN: 555326363
Department: Accounting
Salary: $45727.00

Name: Sampson, Grace
.......

Name: Sampson, Grace
.......

Name: Sampson, Grace
........

Name: Sampson, Grace
.......

Name: Sampson, Grace
........

Name: Sampson, Grace
........

Name: Wise, Dennis
SSN: 123456789
Department: Marketing
Salary: $56743.00

Name: Wise, Dennis
........

Name: Wise, Dennis
.........

Name: Wise, Dennis
.........

Name: Wise, Dennis
.........

Name: Wise, Dennis
.........

Name: Wise, Dennis
.........

(......... = same as first time mentioned - used to minimize post length)

Obviously not right! Ha!

I tried using just a for loop like:

for (int index = 0; index < numEmployees; index++)
     employee_list[index].print();

But this doesnt print out anything, so the first option should work - but maybe just the logic of the insertion sort it off (although copy pasted from the assignment page + changes).

Any ideas as to why the printing is off?

Thanks again

I figured out where my problem is... it is not with anything posted above, it is in fact with my greaterThan() bool function.

This function takes 2 classes, a temp and the original, and compares 2 last names, if the last name is say apple, and the other is bear, apple comes first, so it should return 1 (using strcmp - and my understanding of the strcmp() function). If say, it was compare bear, apple - apple comes first, so it would return 0, and if it were apple, apple, it would return 0.

In this last case, you would then compare first names of the two that were the same last... get it?

So basically... if i return true, they should swap, else, it returns false, don't swap... at least i think thats the damn idea

bool greaterThan(Name name1, Name name2)
{
if (strcmp(name1.getLastName(), name2.getLastName()) > 0)
   {
     return true;
   }
   else if (strcmp(name1.getLastName(), name2.getLastName()) < 0)
   {
     return false;
   }
if (strcmp(name1.getLastName(), name2.getLastName()) == 0)
  {
     if (strcmp(name1.getFirstName(), name2.getFirstName()) > 0)
     {
       return true;
     }
     else if (strcmp(name1.getFirstName(), name2.getFirstName()) < 0)
     {
       return false;
     }
  }
return 0;
}

This code is a mess to me - and i think it SHOULD be right - but obviously not, it sorts the first 2, then prints wise, dennis's info for the rest of them! Whoops!

Thanks

What your greaterThan( ) is doing is returning true if the second argument comes first in sorting order, false if the first argument comes first or if it's a tie.

Your final return statement should also be a bool return rather than 0.

The test for last names being equal is unnecessary, as you only get there if that's the case.

That being said, it appears your sort works correctly. The print statement in the sort - why is there an index on temp? It's not an array. And printing from the sort doesn't really help as the data moves around.

Your little loop for printing looks OK. Do you try executing it before sorting?

Changing the position of the printing loop solved my problem. Good call. It now prints correctly - good help as always. When it comes to input streams, the basics, i understand, eg - reading a file, storing into a variable, etc...but i have something like this:

void changeDepartment(ifstream & transFile, Employee employeeList[], int numEmployees)

What is the first part doing.... i tried looking it up in my book, and its sending the ifstream object to the function? THe & means the address of - right? If i could get an explanation of whats going on here - the prject is pretty much complete.

I think i cheated by doing this in my processTransactions() function -

else if (transType == 4)
             {
             char socNumber[10];
             char newDepart[16];
             socNumber[0] = '\0';
             newDepart[0] = '\0';              
             inFile >> socNumber;
             inFile >> newDepart;
             cout << "\nSearch for SS#: ************" << socNumber << endl;
             cout << "New Depart: **************" << newDepart << endl;

I know i get given a file that looks like:
1
2
4 123456789 34500
3
2
5 000000000 Sales

So i think what i did may have been cheating, but if i take away the inFile reads - my program goes nuts at the 4, cause it is expecting something other than a soc etc i think...

Does this make sense? Just throwing that out there - i am getting help from my TA today after recitation - should be good after that...but different eyes sometimes helps.

Cheers again

The ifstream object (all ..stream objects, for that matter) are pretty big, complex things. Any time you pass it to a function, the expectation is that you will be reading or writing with some stream, and that changes its state. For the ifstream, you change the file position pointer and the status of the stream (is it in a good state, has it reached EOF, etc), and this needs to be known at all functions to which the stream is passed, and at the function that owns it. Thus, it MUST be passed by reference, which current compilers enforce. You will find that you cannot pass a stream variable by value - you should get a compiler error.

As to your second question, if you don't read the social and the department, those characters are still sitting in the file waiting to be read. Whatever happens after that bit of code will grab the next char(s) and attempt to interpret them, probably incorrectly. Taken on its own, that code looks like it should do what you want.

I got my stupid function to work with the ifstream objects etc being sent to the functions.

A new problem has arisen, (of course right?). I have been working on this new problem for the past 3 hrs or so ... and no matter how i format my functions, i cant get the output to work quite right.... as of now the output is this:

............ - sorted list of employees - works just fine

Change Department: Department changed to Sales for SSN: 327450300

Change Department: No match found for SSN: 327450300
^SHOULD NOT BE HERE

Change Department: No match found for SSN: 111111111

Change Salary: Salary changed to $48400.00 for SSN: 101328745

Change Department: No match found for SSN: 101328745
^SHOULD NOT BE HERE

....... (sorted list of names - works just fine)

Change Department: No match found for SSN: 999999999

Change Salary: Salary changed to $44600.00 for SSN: 302457630

Change Department: No match found for SSN: 302457630
^ this part should NOT be here - after changing the salary - loop should not check again and use this cout....

...... (another sorted list by department - works just fine)

So as you can see there are a couple of statements that should NOT print - but for some reason still do - i will give you the 2 functions that this stuff is coming from - and see if there is a logic error in my code...thanks again.

CODE FOR CHANGE DEPARTMENT ( 4 999999999 Sales)

(input file gives me 4 (code for department change needed), SS to search for, new department name)

void changeDepartment(ifstream &transFile, Employee employee_list[], int numEmployees)
{
    char socNumber[10];
    char newDepart[16];
    socNumber[0] = '\0';
    newDepart[0] = '\0';              
    transFile >> socNumber;
    transFile >> newDepart;
    for (int i = 0; i < numEmployees; i++)
         {
         if (strcmp(employee_list[i].getSSN(), socNumber) == 0)
            {
            employee_list[i].setDepartment(newDepart);
            cout << "\nChange Department: Department changed to " 
                 << newDepart << " for SSN: " << employee_list[i].getSSN() 
                 << endl;
            }
            else if (i == numEmployees - 1)
            {
            cout << "\nChange Department: No match found for SSN: " << socNumber <<endl;
            }
         } 
}

if you need to see one of the functions/methods i call - let me know- you shouldnt tho - they are only one liners setx to y etc...

CODE FOR CHANGESALARY

void changeSalary(ifstream &transFile, Employee employee_list[], int numEmployees)
{
    char socNumber[10];
    double newSalary;
    socNumber[0] = '\0';              
    transFile >> socNumber;
    transFile >> newSalary;
    for (int i = 0; i < numEmployees; i++)
         {

            if (strcmp(employee_list[i].getSSN(), socNumber) == 0)
            {
            employee_list[i].setSalary(newSalary);
            cout << "\nChange Salary: Salary changed to $" << setprecision(2)
                 << fixed << newSalary << " for SSN: " 
                 << employee_list[i].getSSN() << endl;
            }
           else if (i == numEmployees - 1)
            {
            cout << "\nChange Department: No match found for SSN: " << socNumber <<endl;
            }
         } 
}

So - as you can see the idea is to check the social security against the one given from the input file - search through current employees - if the SS matches, perform the change (new salary or new department depending on transaction code given (either 4 or 5)).
If the code goes through until the end (IE the number of employees - then no match was found - and should print an error code with the SS number that was searched for).
As you can see above through the output - the current social for the REAL person is used, not the social security number that is searched for - this is WRONG...

Any ideas would be awesome - this is the last step...

I tried moving the IF statement before the searching IF statement - but i still get errors - i found out that numEployees = 16 - while the loop only goes to 15. ... any ideas?

Thanks again .....

Your loop is set up to always go to the end of the list. If you find a match, you process it, and continue searching through the list. Hit end of list, display the not found message.

Either exit the loop with a break statement after finding a match (not my preference) or change it to a while loop. If the loop finds a match, it exits upon processing. If it does not find a match, you'll know this by the index being equal to array size when the loop is done, thus know to display the not found message. (This is my preference)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.