C++ convert struct to class

Hello, I just want to have couple question about this code, I am currently converting a struct to class. Problem is I have never encounter writing a program with I/O in the class. I am intend to create a function of public class to read write all the data into private class members. But is it better to use constructor to doing that

This is my original struct code
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  #include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

#define a_row 10
#define a_col 6

ifstream inputname, inputscore;

struct studentRecord
{
	string name;
	int grade;
	int sum;
	double average;
	char letter;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void readStudentData(studentRecord n[a_row], studentRecord g[a_row][a_col])
{
	inputname.open("name.txt");
	inputscore.open("score.txt");

	inputname.open("name.txt");
	if (!inputname) perror("File not found ");
	else
		cout << "File successfully opened" << endl;

	for (int r = 0; r < a_row; r++)
	{
		getline(inputname, (n[r].name));
		for (int i = 0; i < a_col; i++)
		{
			inputscore >> g[r][i].grade;
		}

	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void printStudentData1(studentRecord n[a_row], studentRecord g[a_row][a_col])
{
	for (int r = 0; r < a_row; r++)
	{
		cout << n[r].name << "\t";
		for (int i = 0; i < a_col; i++)
		{
			cout << g[r][i].grade << " " << "\t";
		}
		cout << endl;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void sumOfGrade(studentRecord g[a_row][a_col], studentRecord s[a_row])
{
	for (int r = 0; r < a_row; r++)
	{
		for (int i = 0; i < a_col; i++)
		{
			s[r].sum = s[r].sum + g[r][i].grade;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void averageGrade(studentRecord s[a_row], studentRecord a[a_row])
{
	for (int i = 0; i < a_row; i++)
	{
		a[i].average = s[i].sum / (static_cast <double> (a_col));
	}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void letterGrade(studentRecord a[a_row], studentRecord l[a_row])
{
	for (int i = 0; i < a_row; i++)
	{
		if (a[i].average >= 90)
		{
			l[i].letter = 'A';
		}
		else if (a[i].average >= 80)
		{
			l[i].letter = 'B';
		}
		else if (a[i].average >= 70)
		{
			l[i].letter = 'C';
		}
		else if (a[i].average >= 60)
		{
			l[i].letter = 'D';
		}
		else
		{
			l[i].letter = 'F';
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void printStudentData2(studentRecord n[a_row], studentRecord g[a_row][a_col], studentRecord s[a_row], studentRecord a[a_row], studentRecord l[a_row])
{
	for (int r = 0; r < a_row; r++)
	{
		for (int i = 0; i < a_col; a++)
		{
			cout << n[r].name << "\t";
			cout << "Total: " << s[r].sum << endl;
			cout << "Average: " << a[r].average << endl;
			cout << "Grade: " << l[r].letter << endl;
			cout << g[r][i].grade << endl;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void main()
{
	studentRecord name[a_row];
	studentRecord grade[a_row][a_col];
	studentRecord sum[a_row];
	studentRecord average[a_row];
	studentRecord letter[a_row];

	readStudentData(name, grade);
	printStudentData1(name, grade);
	sumOfGrade(grade, sum);
	averageGrade(sum, average);
	letterGrade(average, letter);
	printStudentData2(name, grade, sum, average, letter);

	inputname.close();
	inputscore.close();
	system("pause");
}


Before you convert this to a class, there are some problems you need to cleanup.

Lines 26,29: You open inputname twice.

Lines 138-142: Your studentRecord struct is an aggregate of these fields. You don't want to define a studentRecord for each element.
 
  studentRecord rec[a_row];  // Define an array of structures 


But is it better to use constructor to doing that

No. You can't return an error from a constructor. It's better to have a separate functions to read / write instances of your class.

Oh sorry, what I meant was using constructor to write I/O to read and store data into private member ? is it okay to doing that ?
Also this is how far I have done with I/O with class, somehow it's always give me this error

http://i.imgur.com/c2LzgCz.png

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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

#define a_row 10
#define a_col 6

ifstream inputname, inputscore;

class studentRecord
{
private:
	string name[a_row];
	int grade[a_col];
	int sum;
	double average;
	char letter;
public:
	studentRecord();
	/*void readStudentData(string name, int grade);
	void printStudentData(string name, int grade);
	int sumOfGrade(int grade, int sum);
	double averageGrade(int sum, double average);
	void letterGrade(double average, char letter);
	void printStudentData2(string name, int grade, int sum, double average, char letter);*/
};

studentRecord::studentRecord()
{
	inputname.open("name.txt");
	inputscore.open("grade.txt");

	for (int r = 0; r < a_row; r++)
	{
		inputname >> name[a_row];
		for (int i = 0; i < a_col; i++)
		{
			inputscore >> grade[a_col];
		}
	}
	
}

//int studentRecord::sumOfGrade(int grade, int sum)
//{
//
//}

void main()
{
	studentRecord student;
	system("pause");
}
You're still missing a couple of points.

1) A student record object should represent ONE and only one student. name should not be an array. You want to represent multiple students by having an array (or preferably a vector) of studentRecords as I suggested in my previous post.

2) As I also suggested in my previous post, it's not a good idea to open and read a file in a constructor. There are two reasons for this.
a) A studentRecord constructor initializes ONE studentRecord object. You can't read an entire file into an object that represents only one student.
b) Lines 33-34: What happens if either file fails to open? You continue as if nothing has gone wrong.

Line 38,41: These are out of bound references.

Line 52: main must return type int.

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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

const int MAX_STUDENTS = 10;    // Use meaningful names
const int MAX_GRADES = 6;


class studentRecord
{
private:
	string name;
	int grade[MAX_GRADES];
	int sum;
	double average;
	char letter;
public:
	studentRecord();
	bool Read (istream & inputname, istream & inputscore);
};

//  Constructor
studentRecord::studentRecord ()
{}

bool studentRecord::Read (istream & inputname, istream & inputscore)
{   if (! (inputname >> name))
        return false;  //  failed to read a record
    sum = 0;        
    for (int i = 0; i < MAX_GRADES; i++)
    {   inputscore >> grade[i];    // Could use some error handling here if the read fails
        sum += grade[i];
    }        
    return true;
}

int main()
{   ifstream inputname, inputscore;
    studentRecord student[MAX_STUDENTS];
    int i = 0;
    
   	inputname.open("name.txt");
	inputscore.open("grade.txt");   
	if (inputname.fail() || inputscore.fail())
    {   cout << "Unable to open input file" << endl;
        return 1;
    }	
    while (i < MAX_STUDENTS && student[i].Read (inputname, inputscore))        
         i++;
  system("pause");
  return 0;
}



Last edited on
Topic archived. No new replies allowed.