Today was my first time trying composition. It's for a lab project due Friday, and I have a lot of tomorrow to work on it. However, up until we have just been using one class per program. Now, my teacher wants us to use composition and arrays, despite only lecturing on them for a few minutes. Worse, there is no section on composition (and arrays in compositions) in our notes/textbook. So, could you check this code and tell me if I'm on the right track. I don't even need help with syntactical errors (yet); I just need an idea of what I need to do, and what I'm not understanding about composition.

There are five files, and an input file. And the program (as you can see from the input file) reads the student info and stores it in an array and then outputs (1) all information in a table, (2) a student searched by last name, (3) lowest gpa student information, (4) highest units gpa information.

Thank you very much.

student.h

#ifndef student_H
#define student_H

#include <string>

using namespace std;

class Student{
	public:
		void set_Name(string, string); 	
		bool readStudent(ifstream &);
		void printStudent () const;
		Student();
		string get_Last();
		string get_First();
		void set_Major(string);
		string get_Major( );
		int get_Units();
		void set_Units(int);
		float get_GPA();
		void set_GPA(float);
	private:
		string  First, Last;
		int		Units;
		float	GPA;
		string	Major; 
};

#endif

Student Implementation

#include <iostream>
#include <fstream>
#include "student.h"

using namespace std;
void Student::set_Name(string first, string last){
	First = first;
	Last = last ;		
}

bool Student::readStudent(ifstream & fin){
	getline(fin, First);
	if (fin){
	 	getline(fin, Last);
		getline(fin, Major);
		fin >> Units ;
		fin >> GPA ;
		fin.ignore(10,'\n');
	}
	return (fin.good());
}
void Student::printStudent () const
{
	cout <<"\n\tStudent information:\n";
	cout << "Name:   \t" << Last +", "+ First <<endl ;
	cout << "Major:  \t" << Major << endl;
	cout << "Units : \t"<< Units <<endl;
	cout << "GPA:    \t" << GPA << endl <<endl;
}

Student::Student(){
	Units = 0 ;
	GPA = 0 ;
};
string Student::get_Last(){
	return Last; 
}

void Student::set_Major(string t_major){
	Major = t_major;
}
int Student::get_Units(){
	return Units;
}	
float Student::get_GPA(){
	return GPA;
}			
string Student::get_First(){
	return First ;
}
string Student::get_Major( ){
	return Major ;
}
void Student::set_Units(int units){
	Units = units ;
}
void Student::set_GPA(float gpa){
	GPA = gpa ;
}

school.h

#ifndef school_H
#define school_H
#define SIZE 15

#include <string>
#include "student.h"

using namespace std;

class School{
	public:
		int read_list(Student list[], int size);
		bool open_file(ifstream &fin);
		void print_list(Student list[], int size);
		int search(Student list[], int);  
		int low_GPA(Student list[], int);
		int high_Units(Student list[], int);
	private:
		Student CS101[SIZE];
};

#endif

School Implementation

#include <iostream>
#include <fstream>
#include <iomanip>
#include "school.h"

using namespace std;
int School::search(Student list[], int size){
	string	target;

	cout <<"\nPlease enter last name of student to locate:(all lower case) ";
	getline(cin, target);
	if (target.length()> 0){
		target[0] = toupper(target[0]); // convert first character to lower case
		for (int i = 0 ; i < size ; i++){
			if((int)(list[i].get_Last()).find(target)>=0 )
				return i ;
		}
	}
	else
		cout <<"No name was entered.\n";
	return -1 ;  // Student was not found on the list;
}

int School::read_list(Student list[], int size)
{
	ifstream fin ;
	bool	flag ;
	int i = 0 ;
	if (open_file(fin))
	{
		flag = list[i].readStudent(fin);
		while(flag && !fin.eof())
		{
			i++;
			if (i < size)
				flag = list[i].readStudent(fin);
			else
			{
				cout <<"\n*********** Array is full.\n";
				break ;
			}
		}
	}
	return i ;
}

bool School::open_file(ifstream &fin)
{
	string  f_name ;
	int		counter = 3 ;
	bool	flag = true;
	
	do{
		flag = true ;
		cout <<"Please enter input file name: ";
		getline(cin, f_name) ;
		fin.open(f_name.c_str());
		if (fin.fail())
		{
			counter-- ;
			cout <<"\nBad file name, you have "<< counter << " chances, try again.\n" ;
			fin.clear();
			flag =  false ;
		}
	}while (!flag && counter >= 0);
	return flag ;
}
void School::print_list(Student list[], int size)
{
	if (size > 0)
	{
		cout <<endl <<endl<<left<< setprecision(2) <<showpoint<<fixed;
		cout << setw(50)<< "Name"<<setw(30)<<"Major"<<setw(12)<<"Units"<<"GPA\n";
		cout << setfill('-') << setw(100)<<"-" << setfill(' ')<<endl;
		for (int i = 0 ; i < size ; i++){
			cout << setw(50)<<list[i].get_Last() + ", " + list[i].get_First() << setw(30) << list[i].get_Major();
			cout << setw(12) << list[i].get_Units() << list[i].get_GPA() << endl;
		}
		cout <<endl <<endl << "****** end of report ******\n\n";
	}
}

int School::low_GPA(Student list[], int size)
{
	int lowIndex;
	float first, second, lowGPA = 5.0;
	if(size > 0){
		for (int i = 0 ; i < size ; i++){
			first = list[i].CS101.get_GPA();
			second = list[i+1].CS101.get_GPA();
			if (first < lowGPA && first > 0.00){
				lowIndex = i;
				lowGPA = list[i].CS101.get_GPA();
			}
			if (second < lowGPA && second > 0.00){
				lowIndex = (i+1);
				lowGPA = list[i+1].CS101.get_GPA();
			}
			}
		return lowIndex;
	}		
}

int School::high_Units(Student list[], int size)
{
	int first, second, highIndex, highUnits = 0;
	if(size > 0){
		for (int i = 0 ; i < size ; i++){
			first = list[i].CS101.get_Units();
			second = list[i+1].CS101.get_Units();
			if (first > highUnits){
				highIndex = i;
				highUnits = list[i].CS101.get_Units();
		
			}
			if (second > highUnits){
				highIndex = (i+1);
				highUnits = list[i+1].CS101.get_Units();
			}
			}
		return highIndex;
	}
}

Main/Driver

#include <iostream>
#include <fstream>
#include <iomanip>
#include "student.h"
#include "school.h"
#define SIZE 15
using namespace std;


int main()
{
	Student CS101[SIZE];
	int size, index;
	
	ifstream fin;
	
	size = CS101.read_list(CS101, SIZE);
	CS101.print_list(CS101,size);	
	if(size > 0){
		index = CS101.search(CS101, size);
		if (index != -1){
			cout << "You searched for: " << endl;
			CS101[index].printStudent();
		}
		else
			cout << "Student is not on the list.\n" ;

		index = CS101.low_GPA(CS101, size);
		if (index != -1){
			cout << endl << endl;
			cout << "The student with the lowest GPA is: " << endl;
			CS101[index].printStudent();		
		}
		
		index = CS101.high_Units(CS101, size);
		if (index != -1){
			cout << "The student with the highest number of units is: " << endl;
			CS101[index].printStudent();		
		}		
	}
	fin.close();
	return 0;
}

Input File: student.txt

Joe
Smith Jr.
Electrical Engineering
45 3.45
Nancy Karen
Brown
Industrial Engineering
34 4.0
Adam
Jonhson
Computer Science
56 3.89
Gorden
Khalbandy
Mechanical Engineering
89 3.28
Alan
Jackson
Computer Science
34 3.95

Recommended Answers

All 4 Replies

Thursday bump. Any tips on composition/arrays would be welcomed, too.

What exactly do you need help with?

A composition is when your class is composed of some object.

Here is an example :

class Name {  public : string aName; };

since string is a class and aName is an object, then one could say that
Name is composed of an object of the string class.


And I guess when you say arrays, in this case you mean something like this :

int main()
{
    Names president[10];
    return 0;
}

1) I get this in my compiler: " company.h.gch: too short to be a PCH file
" What does it mean?

2) What does "void value..." mean.
Compiler:

companyImp.cpp: In member function 'int Company::read_list(int)':
companyImp.cpp:55: error: void value not ignored as it ought to be
companyImp.cpp:60: error: void value not ignored as it ought to be

Code from line 55:

flag = list[i].readData1(fin);
		while(flag && !fin.eof())
		{
			i++;
			if (i < size)
				flag = list[i].readData1(fin);

3) None of the following makes sense. The compiler says:

companyImp.cpp: In member function 'void Company::process_list(int)':
companyImp.cpp:75: error: 'int' is not a template
companyImp.cpp:75: error: 'size' cannot appear in a constant-expression
companyImp.cpp:75: error: expected primary-expression before 'int'
companyImp.cpp:75: error: expected `;' before 'int'
companyImp.cpp:75: error: expected primary-expression before 'int'
companyImp.cpp:75: error: expected `)' before 'int'
companyImp.cpp:75: error: declaration does not declare anything
companyImp.cpp:75: error: expected `;' before ')' token

And the code from line 71:

void Company::process_list (int size)
{

	if (size > 0)
		for (int i = 0; int < size; i++){               //line 75
			list[i].setSkillPay();
			list[i].calcGross();
			list[i].setBenefitCost();
			list[i].calcContAmountAndTotal();
			list[i].calcGrossDed();
			list[i].calcTax();
			list[i].calcNet();	
	}
}

4) Is there a way to use the length function for double type variables. For instance, I got this compiler message back:

companyImp.cpp: In member function 'void Company::searchID(int)':
companyImp.cpp:187: error: request for member 'length' in 'target', which is of non-class type 'double'
companyImp.cpp:188: error: invalid types 'double[int]' for array subscript
companyImp.cpp:188: error: invalid types 'double[int]' for array subscript

And here's the code. I'm confused because I did the exact same thing with a string target and it worked.

void Company::searchID(ofstream &fout1, int size)
{
	double target;
	int i;

	cout << endl << "Please enter the ID number of the employee to locate: ";
	cin >> target;
	cin.ignore(10,'\n');	
	if (target.length()> 0){
		target[0] = toupper(target[0]); // convert first character to lower case
		for (i = 0 ; i < size ; i++){
			if((int)(list[i].getLast()).find(target)>=0 ){
			cout << "You searched for: " << endl;
			list[i].printFile1(fout 1);
			}
		}
	}
	else
		cout << "Employee ID entered was not on the company list." << endl;
}

5) This.

companyImp.cpp:208: error: no match for 'operator>' in 'Employee::getLast()() > ((Company*)this)->Company::list[(i + 1)].Employee::getLast'
companyImp.cpp:210: error: no match for 'operator=' in 'temp = ((Company*)this)->Company::list[i]'
/auto/usc/gnu/gcc/4.2.1/bin/../lib/gcc/sparc-sun-solaris2.10/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:490: note: candidates are: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
/auto/usc/gnu/gcc/4.2.1/bin/../lib/gcc/sparc-sun-solaris2.10/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:498: note:                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
/auto/usc/gnu/gcc/4.2.1/bin/../lib/gcc/sparc-sun-solaris2.10/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:509: note:                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
companyImp.cpp:212: error: no match for 'operator=' in '((Company*)this)->Company::list[(i + 1)] = temp'
employee.h:292: note: candidates are: Employee& Employee::operator=(const Employee&)
companyImp.cpp: At global scope:

Line 208-292:

if (list[i].getLast() > list[i+1].getLast)
			{
				temp = list[i];
				list[i] = list[i+1];
				list[i+1] = temp;
				flag = false;
			}
	}while (!flag);
}

void Company::Add(ofstream fout1, int size)
{	
	string firstName, lastName;
	int i, skill, benefitType;
	double contPercent, hours, taxID;
	
	if (size >= 50)
		cout << "Cannot add. Array is full." << endl;
	else{
		cout << "Please enter the employee's skill type:";
		cin >> skill;
		cout << "Please enter the employee's benefit code:"; 
		cin >> benefitType;
		cout << "Please enter the employee's retirement contribution percent:";
		cin >> contPercent;
		cout << "Please enter the employee's hours worked:";
		cin >> hours;
		cout << "Please enter the employee's tax ID:";
		cin >> taxID;	
		cout << "Please enter the employee's first and last name:"; 
		cin >> firstName >> lastName;
	}
	i = searchName(fout1, lastName);
	if (i != -1)
		cout << "Employee entered is already on the list." << endl;
	else{
		i = size;
		list[i].setName(firstName, lastName);
		list[i].setSkill(skill);
		list[i].setBenefitType(benefitType);
		list[i].setContPercent(contPercent);
		list[i].setHours(hours);
		list[i].setTaxID(taxID);
	
		process_list (int size);
		calcSums(int size);		
		size++;
	}
}

void Company::search_and_destroy(int size)
{
	string target;
	int index;
	
	cout << "Please enter the last name (all lower case) of the employee you wish to delete: ";
	getline(cin, target);
	if (target.length()> 0){
		target[0] = toupper(target[0]); // convert first character to lower case
		for (int i = 0; i < size ; i++){
			if((int)(list[i].getLast()).find(target)>=0 ){
				cout << "The employee you selected was deleted.";
				index = i;
			}
			}
		for (i = 0; i < size; i++)
			list[i] = list[i+1];
			list[size-1] = 0;
			size--;
			}
		}
	else
		cout << "Employee Name entered was not on the company list." << endl;	
}

void Company::search_and_change(int size)
{
	string last, newFirst, newLast, target;
	int newSkill;
	double newHours, newID;
	
	cout << "Please enter the last name (all lower case) of the employee you wish to change: ";
	getline(cin, last);
	if (target.length()> 0){
		target[0] = toupper(target[0]); // convert first character to lower c

companyImp.cpp: In member function 'int Company::read_list(int)':
companyImp.cpp:55: error: void value not ignored as it ought to be
companyImp.cpp:60: error: void value not ignored as it ought to be

What is the read_student() method supposed to return (I don't see it but I'm sure it's in another file). Or readData for that matter. If it is a void function and you're trying to assign that to flag then it's balking.

companyImp.cpp: In member function 'void Company::process_list(int)':
companyImp.cpp:75: error: 'int' is not a template
companyImp.cpp:75: error: 'size' cannot appear in a constant-expression

You have a type where a variable should be. In the condition portion of your for loop you have int < size, it should be i, and then the rest of the errors (in that grouping) will fall out
(which is commonplace and why fixing the first one can make many others go away) if (list[i].getLast() > list[i+1].getLast) you forgot a () after the second getLast

companyImp.cpp: In member function 'void Company::searchID(int)':
companyImp.cpp:187: error: request for member 'length' in 'target', which is of non-class type 'double'
companyImp.cpp:188: error: invalid types 'double[int]' for array subscript
companyImp.cpp:188: error: invalid types 'double[int]' for array subscript

target is not a string it has no length() function. I think you mean to have it as a string after all the manipulations.

I'm sure there will be other little ones along the way but those are most of the biggies. Just take it one error at a time.

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.