read file problem

Pages: 123
Any senior help?
Any senior help?
patience, please, as a senior I'm not the fastest anymore...

so should i let user choose which course he want to enroll ?
this sounds like a plan.

use your already existing void enrollStudent( Course *theCourse , int sizeCourse ), but different. like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void enrollStudent( Course *theCourse , int sizeCourse ){
int choice = 0;

cout << "0. exit" << endl;
for(int i = 0; i < sizeCourse; ++i)
{
         cout << i << ". " << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
}
cout << "Enter Your choice : ";
cin   >> choice;

if((choice > 0) and (choice < sizeCourse ))
         theCourse[choice - 1].enrollStudent();
else if(choice != 0)
         cout << "Invalid Input ! " << endl;
         
}
simple, isn't it? Btw: within your enrollStudent() you must check if the maximum number of students is already reached

Should i do it at the start place? or ?
You call it from the menu, like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "course.h"

int main(){
...	

start:	cout << "\tEnrollment System College Penang" << endl
			 << "-----------------------------------------------------" << endl << endl
			 << "1. Enroll a new student into a course" << endl
			 << "2. Remove a student from a course "    << endl
			 << "3. Modify a course detail"             << endl
			 << "4. Generate grade list"                << endl
			 << "5. Save to file "                      << endl << endl
			 << "Enter Choice : ";

	cin  >> choice;

	switch( choice ){
	case 1:
		enrollStudent( theCourse , sizeCourse );
		getch();
		break;
	default:
		cout << "Invalid Input ! Please re-enter ! " << endl;
		getch();
		system( "cls" );
		goto start;
	}

	system( "pause" );
	return 0;
}


I recommend doing the same for readRecord(). I.e. having a global
void readRecord( ifstream &inFile ,Course *theCourse, int &sizeCourse )
for all courses and a class member
void readRecord( ifstream &inFile )
to read the course details. Which would greatly improve the legibility of your code
@code777
sorry and i shall take your advise . sorry for that

for my readfunction() i change it instead of a class member . here my class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>

using namespace std;

class Course{
private:
	string courseCode;
	string courseName;
	int credit;
	int numOfStudent;
public:

	struct Student{
		string studentID;
		string studentName;
		double studentMarks;
	}theStudent[30];

	Course();
	
	void setCourseCode( string );
	string getCourseCode();

	void setCourseName( string );
	string getCourseName();

	void setCredit( int );
	int getCredit();

	void setNumOfStudent( int );
	int getNumOfStudent();

	void setStudentID( string );
	string getStudentID();

	void setStudentMarks( double );
	double getStudentMarks();

	void readRecord( ifstream & , int & );
	void enrollStudent( int & );
	void RemoveStudent( int & );
	void ModifyCourse( int & );
	void GradeList( int & );
	void writeRecord(  int & );
};


and here my read function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void readRecord( ifstream &inFile , int &sizeCourse ){

	Course *theCourse;
	string SubjectCode;
	string SubjectName;
	string StudentName;
	int theCredit = 0;
	int sizeOfStudent = 0;
	string filename;

	if ( inFile.is_open() ){
		inFile.ignore();
		for( int i = 0 ; i < sizeCourse ; i++ ){
			getline( inFile , SubjectCode );
			theCourse[i].setCourseCode( SubjectCode );

			getline( inFile , SubjectName );
			theCourse[i].setCourseName( SubjectName );

			inFile >> theCredit;
			theCourse[i].setCredit( theCredit);

			inFile >> sizeOfStudent;
			theCourse[i].setNumOfStudent( sizeOfStudent );
			inFile.ignore();

			for ( int z = 0 ; z < sizeOfStudent ; z++ ){
				getline( inFile , theCourse[i].theStudent[z].studentName);
				inFile >> theCourse[i].theStudent[z].studentMarks;
				inFile.ignore();
			}
		}
	}
	cout << sizeCourse  << endl;
	for( int i = 0 ; i < sizeCourse ; i++ ){
		cout << theCourse[i].getCourseCode() << endl
			 << theCourse[i].getCourseName() << endl
			 << theCourse[i].getCredit() << endl
			 << theCourse[i].getNumOfStudent() << endl;
			 for( int z = 0 ; z < theCourse[i].getNumOfStudent() ; z++ ){
				 cout << theCourse[i].theStudent[z].studentName << endl
					  << theCourse[i].theStudent[z].studentMarks<< endl;
			 }
	}
}


and here is my enroll function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void Course :: enrollStudent( int& numOfCourse ){

	Course *theCourse;
	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << i << "." << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
	}

	cout << "Enter Your Choice : ";
	cin  >> choice;

	if( choice > 0 && choice < numOfCourse )
         theCourse[choice - 1].enrollStudent( numOfCourse );
	else if(choice != 0)
         cout << "Invalid Input ! " << endl;
         

	cin.ignore();

	do{
		cout << "Enter student name : ";
		getline( cin,theStudent[numOfStudent].studentName );
	
		cout << "Enter student's mark : ";
		double studentMarks;
		cin  >> theStudent[numOfStudent].studentMarks;

		numOfStudent++;

		if( numOfStudent > 30 )
			cout << " The number of student enrolled for this course are full ! " << endl;//Display error message if maximum student reached
	}while( numOfStudent < 31 );//Do checking on the number of student that enroll for the course
}


my main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "course.h"

int main(){
	
	string filename;
	Course *theCourse;
	int numOfCourse = 0;
	int choice = 0;
	ifstream inFile;

	cout << "Enter filename to read : ";
	getline( cin , filename );
	cout << endl;

	inFile.open( filename.c_str() );
	
	if( inFile.fail() )
		cout << "Unable to open file !" << endl;
	inFile >> numOfCourse;

	theCourse = new Course[numOfCourse];//dynamic array created

	theCourse->readRecord( inFile, numOfCourse );
	getch();
	system( "cls" );

start:	cout << "\tEnrollment System INTI Penang" << endl
			 << "-----------------------------------------------------" << endl << endl
			 << "1. Enroll a new student into a course" << endl
			 << "2. Remove a student from a course "    << endl
			 << "3. Modify a course detail"             << endl
			 << "4. Generate grade list"                << endl
			 << "5. Save to file "                      << endl << endl
			 << "Enter Choice : ";

	cin  >> choice;

	switch( choice ){
	case 1:
		theCourse->enrollStudent( numOfCourse );
		getch();
		break;
	default:
		cout << "Invalid Input ! Please re-enter ! " << endl;
		getch();
		system( "cls" );
		goto start;
	}

	system( "pause" );
	return 0;
}
my question is . i having some error

fatal error LNK1120: 1 unresolved externals

and i feel that when i pass the parameter isn't wrong already?

i saw that u using only
void Course :: enrollStudent()
without passing any parameter . but i think they should pass a numOfCourse ?
of am i declaring in wrong way already ?
What is the unresolved external? It should give you the name of the function it cannot find.
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall Course::readRecord(class std::basic_ifstream<char,struct std::char_traits<char> > &,int &)" (?readRecord@Course@@QAEXAAV?$basic_ifstream@DU?$char_traits@D@std@@@std@@AAH@Z) referenced in function _main
this my error function?
readRecord is not a class function of the class Course. You missed out a Course:: in the definition.

Alternatively, if it isn't meant to be a class function of the class Course, don't try to call it as one.
Last edited on
okay. but i having an error in my readfunction()
it's say my theCourse is using without been initialized . thats why i having the problem of my course . if i put my [b]readRecord()[/code] in my class function . how should i change inside my code?
That's true. It isn't. Look:

1
2
3
4
5
6
7
8
9
10
11
12
void Course :: enrollStudent( int& numOfCourse ){

	Course *theCourse;
	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << i << "." << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
	}
...


In bold, you can see where you create a pointer and then you start using it, but you never made it point at anything! It's juts some random pointer. What is it meant to be pointing at? If this is meant to be a class function, belong to the Course class, then it's already inside a Course object. You can just use the object variables:
1
2
3
4
5
6
7
8
9
10
11
12
private:
	string courseCode;
	string courseName;
	int credit;
	int numOfStudent;
public:

	struct Student{
		string studentID;
		string studentName;
		double studentMarks;
	}theStudent[30];


i already make it point to theCourse[i].courseCode and the courseName already . from my cout . but i having problem when readFunction(). it's say my theCourse is being use without initialized
i already make it point to theCourse[i].courseCode


I disagree. Look at the code.
1
2
3
4
5
6
7
8
9
10
11
void Course :: enrollStudent( int& numOfCourse ){

	Course *theCourse;
	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << i << "." << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
	}

The first line in bold is where you create the pointer named theCourse. The second line in bold is where you try to use what it is pointing at. Which line of code between those two do you think is setting the pointer to point at something?

The pointer that you set in main.cpp, like this:
theCourse = new Course[numOfCourse];//dynamic array created does not exist inside the functions. The variables that exist inside class functions are:
1) variables you pass in as parameters
2) variables you create in the function
3) class variables that are part of the class
4) Global variables

You are creating a brand new pointer named theCourse in the functions, and it is not being set to point at anything.
Last edited on
erm.. mind to provide a sentences of code? that can refer to? sorry for it
There are many solutions. Here is one:

1
2
3
4
5
6
7
8
9
10
11
void Course :: enrollStudent( int& numOfCourse, Course *theCourse ){

	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << i << "." << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
	}
...


called like this:
theCourse->enrollStudent( numOfCourse, theCourse );
and similarly for other functions.
Last edited on
erm . i get what you mean. because i already create dynamic array in my main , so i have to use it . sorry for it .

as @code777 teaching me the code and he giving me the way to do like this . i have some problem for my enroll function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void Course :: enrollStudent( int& numOfCourse , Course *theCourse ){

	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << (i+1) << "." << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
	}

	cout << "Enter Your Choice : ";
	cin  >> choice;

	if( choice > 0 && choice < numOfCourse )
         theCourse[choice - 1].enrollStudent( numOfCourse , theCourse );
	else if(choice != 0)
         cout << "Invalid Input ! " << endl;
         

	cin.ignore();

	do{
		cout << "Enter student name : ";
		getline( cin,theStudent[numOfStudent].studentName );
	
		cout << "Enter student's mark : ";
		double studentMarks;
		cin  >> theStudent[numOfStudent].studentMarks;

		numOfStudent++;

		if( numOfStudent > 30 )
			cout << " The number of student enrolled for this course are full ! " << endl;//Display error message if maximum student reached
	}while( numOfStudent < 31 );//Do checking on the number of student that enroll for the course
}


from the code we can know that if we press the choice 1 . the function will be recall back . so it will keep call user to input the choice . so what's the advise can give ?

@code777 and @Moschops , both seniors.
erm?
Excuse me I ask you but...are you from Romania?
The point is that you have two enrollStudent() functions. One for the course and one for all courses:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class Course{
...
	void enrollStudent();
...
};

void Course::enrollStudent(){ // This is the class member

	bool found = 0;
	int foundIndex = 0 ;

	cin.ignore();
	cout << "Enter student name : ";
	getline(cin, theStudent[numOfStudent].studentName );
	
	cout << "Enter student's mark : ";
	double studentMarks;
	cin  >> theStudent[numOfStudent].studentMarks;

	numOfStudent++;
}

...

void enrollStudent( Course *theCourse , int sizeCourse ){ // This processes the array
int choice = 0;

cout << "0. exit" << endl;
for(int i = 0; i < sizeCourse; ++i)
{
         cout << i << ". " << theCourse[i].courseCode << " " << theCourse[i].courseName << endl;
}
cout << "Enter Your choice : ";
cin   >> choice;

if((choice > 0) and (choice < sizeCourse ))
         theCourse[choice - 1].enrollStudent();
else if(choice != 0)
         cout << "Invalid Input ! " << endl;
}

...

int main(){
...	

start:	cout << "\tEnrollment System College Penang" << endl
			 << "-----------------------------------------------------" << endl << endl
			 << "1. Enroll a new student into a course" << endl
			 << "2. Remove a student from a course "    << endl
			 << "3. Modify a course detail"             << endl
			 << "4. Generate grade list"                << endl
			 << "5. Save to file "                      << endl << endl
			 << "Enter Choice : ";

	cin  >> choice;

	switch( choice ){
	case 1:
		enrollStudent( theCourse , sizeCourse ); // This calls the function for the processing of the array
		getch();
		break;
	default:
		cout << "Invalid Input ! Please re-enter ! " << endl;
		getch();
		system( "cls" );
		goto start;
	}

	system( "pause" );
	return 0;
}
It is the point of the member functions that they deal with the member variables
this is what i done so far for it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
void Course :: readRecord( ifstream &inFile , int &sizeCourse , Course *theCourse ){

	string SubjectCode;
	string SubjectName;
	string StudentName;
	int theCredit = 0;
	int sizeOfStudent = 0;
	string filename;

	if ( inFile.is_open() ){
		inFile.ignore();
		for( int i = 0 ; i < sizeCourse ; i++ ){
			getline( inFile , SubjectCode );
			theCourse[i].setCourseCode( SubjectCode );

			getline( inFile , SubjectName );
			theCourse[i].setCourseName( SubjectName );

			inFile >> theCredit;
			theCourse[i].setCredit( theCredit);

			inFile >> sizeOfStudent;
			theCourse[i].setNumOfStudent( sizeOfStudent );
			inFile.ignore();

			for ( int z = 0 ; z < sizeOfStudent ; z++ ){
				getline( inFile , theCourse[i].theStudent[z].studentName);
				inFile >> theCourse[i].theStudent[z].studentMarks;
				inFile.ignore();
			}
		}
	}
	cout << sizeCourse  << endl;
	for( int i = 0 ; i < sizeCourse ; i++ ){
		cout << theCourse[i].getCourseCode() << endl
			 << theCourse[i].getCourseName() << endl
			 << theCourse[i].getCredit() << endl
			 << theCourse[i].getNumOfStudent() << endl;
			 for( int z = 0 ; z < theCourse[i].getNumOfStudent() ; z++ ){
				 cout << theCourse[i].theStudent[z].studentName << endl
					  << theCourse[i].theStudent[z].studentMarks<< endl;
			 }
	}
}

void Course::enrollStudent(){ // This is the class member

	bool found = 0;
	int foundIndex = 0 ;

	do{
		cin.ignore();
		cout << "Enter student name : ";
		getline(cin, theStudent[numOfStudent].studentName );
	
		cout << "Enter student's mark : ";
		double studentMarks;
		cin  >> theStudent[numOfStudent].studentMarks;

		numOfStudent++;
		if( numOfStudent > 30 )
				cout << " The number of student enrolled for this course are full ! " << endl;//Display error message if maximum student reached
	}while( numOfStudent < 31 );//Do checking on the number of student that enroll for the course
}

void enrollStudent( Course *theCourse , int& numOfCourse ){

	bool found = 0;
	int foundIndex = 0 ;
	int choice = 0;

	cout << "0.Exit " << endl;
	for( int i = 0 ; i < numOfCourse ; i++ ){
		cout << (i+1) << "." << theCourse[i].getCourseCode() << " " << theCourse[i].getCourseName() << endl;
	

	cout << "Enter Your Choice : ";
	cin  >> choice;

	if( choice > 0 && choice < numOfCourse )
         theCourse[choice - 1].enrollStudent();
	else if(choice != 0)
         cout << "Invalid Input ! " << endl;
		
}


got a senior told me , my readRecord is in wrong state already . isn't?
do my readRecord() should be in member of class , of should it declare as a outside function ? because last time u told me that i only should have 1 parameter which is ifstream &
but then now my read function is have 3 parameters. isn't wrong ?
got a senior told me , my readRecord is in wrong state already . isn't?
do my readRecord() should be in member of class , of should it declare as a outside function ? because last time u told me that i only should have 1 parameter which is ifstream &
but then now my read function is have 3 parameters. isn't wrong ?
No, I didn't say that it's wrong. it could be improved, but it's not necessary. (The same scheme like enrollStudent(), you just need to grasp why enrollStudent() is split this way.)

The loop on line 51 is wrong. numOfStudent must be < 30 otherwise it's out of bounds. This loop will force the user to enter 31 students until he gets an error message
i get it d.
i using if else statement to do it
1
2
3
4
5
6
7
8
9
10
11
12
if( numOfStudent < 31 ){
		cin.ignore();
		cout << "Enter student name : ";
		getline(cin, theStudent[numOfStudent].studentName );
	
		cout << "Enter student's mark : ";
		cin  >> theStudent[numOfStudent].studentMarks;

		numOfStudent++;
	}
	else if( numOfStudent > 30 )
		cout << " The number of student enrolled for this course are full ! " << endl;//Display error message if maximum student reached 


now for my enroll student.
after i enroll the newstudent.
i go back to my readRecord() . but then . now the problem is . while i read back my file. it's output is like this
1
2
3
4
5
6
7
8
9
10
11
12
13
//Output window
Unable to open file!
2



0
0


0
0
Pages: 123