c++ Program that uses structs and nodes to read data file

I am using a combination of structs and nodes using a heavily modified linked list program to read a data file and print results, I have also commented out what I am trying to do to help people better understand. The only issue is that it has a strange output and I would like some input as to what I could do to fix my current 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
 #include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

struct date
{
	unsigned int month;
	unsigned int day;
	unsigned int year;
};
// Define a structure for a student record. (Note that the Homework and Exams are arrays of numbers. 
// There are 7 homework scores and 3 exam scores.)
struct student_record
{
	string firstname;
	string lastname;		
    date birthdate;
    string year;
    string major;
	string ID;
	double exam_grades[7];
	double homework_grades[3];
	float grade;
    //insert link
    student_record *link;
	};
// Declare an array of student records to hold all the data from the file.
// Read in the student data from the file to initialize the array of student records.
const int RECORDS = 10;    


void print_data(student_record person);
void enter_data(student_record* root);
double get_average(double *array, int length);
void compute_grade(student_record student);
int main(void)
{
        ifstream infile;
        infile.open("/Users/adam/desktop/temp/student_records.txt");
       
        string line;
        student_record *student = new student_record; // Pointer to student_record type
       
        if (!infile)
        {
                cout << "Unable to open the student data file." << endl;
                return 1; // Error code for file open error
        }

        cout << "Student File opened." << endl;
        // Read and ingnore the first line of the file.
        // They are not data lines.

        getline(infile, line);
        

        // Read in the data for the first student
        infile >> student->firstname >> student->lastname >> student->birthdate.month 
                  >> student->birthdate.day >> student->birthdate.year
                   >> student->ID >> student->year >> student->major;
        for (int k = 0; k < 7; k++)
            infile >> student->homework_grades[k];
        
        for (int k = 0; k < 3; k++)
            infile >> student->exam_grades[k];     

        student_record *root=NULL, *new_node;
        
        // making first node
        root=student;
        student->link=NULL;
        
        
        // reading remaining 9 data and making node
        
        for(int i=0;i<9;i++)
        {
                student_record *new_node = new student_record;
                student_record *current_node=root;
                while(current_node->link)                                      // traversing till last so that we can add node there
                {
                        current_node=current_node->link;
                        }
                        
                        infile >> new_node->firstname >> new_node->lastname >> new_node->birthdate.month
                              >> new_node->birthdate.month >> new_node->birthdate.day          // reading data
                               >> new_node->ID >> new_node->year >> new_node->major;
                    //for (int k = 0; k < 7; k++)
            		//infile >> student->homework_grades[k];
        
        		    //for (int k = 0; k < 3; k++)
           		    //infile >> student->exam_grades[k];          
                                
                    current_node->link=new_node;       // adding node
                    new_node->link=NULL;
                }
                
                
                // Printing
                
                
                student_record *current_node=root;
                while(current_node)
                {
                print_data(*current_node);
                
                current_node=current_node->link;
                }
        enter_data(root);
        return 0;
}

void enter_data(student_record *root)
{
    cout << "Enter first and last name." << endl;
    string firstname, lastname;
    cin >> firstname >> lastname;
    student_record* current_node = root;
    while (current_node != nullptr)
    {
        if (current_node->firstname == firstname && current_node->lastname == lastname)
        {
            cout << "Birthdate: " << current_node->birthdate.month << current_node->birthdate.day << current_node->birthdate.year << endl; 
            cout << "ID: " << current_node->ID << endl;
            cout << "Class: " << current_node->year << endl;
            cout << "Major: " << current_node->major << endl;
            cout << "Homeworks: " << current_node->homework_grades << endl;
            cout << "Exams: " << current_node->exam_grades << endl;
            break;
        }
        current_node = current_node->link;
    }
    return;
}

void print_data(student_record person)
{
        cout << endl;
        cout << fixed << setprecision(2) << left;
        cout << person.firstname << " " << person.lastname << endl;
        cout << setw(15) << "Birthdate: " << person.birthdate.month << " " << person.birthdate.day << " " << person.birthdate.year << endl; //error
        cout << setw(15) << "ID: " << person.ID << endl;
        cout << setw(15) << "Class: " << person.year << endl;
        cout << setw(15) << "Major: " << person.major << endl;
        for (int k = 0; k < 1; k++)
        {
            cout << setw(15) << "Homework Average: " << person.homework_grades[k] << endl;
        }
        for (int k = 0; k < 1; k++)
        {
        cout << setw(15) << "Exam Average: " << person.exam_grades[k] << endl;
        }

        cout << right;
        return;
}
// Write a function that will compute the grade for a given student. 
// (Grade should be one of the members of the struct you define.)
// Grade = (average of homework) * 0.40 + (average of exams) * 0.60
// Note: Your program will have to calculate the homework average and the exam average.)
double get_average(double *array, int length)
{
    double sum = 0;
    double avg;
    for(int i=0; i<length; i++)
    {
        sum=sum + array[i];
    }
    avg = sum / length;
    return avg;
}


void compute_grade(student_record student)
{
	cout << "In function compute grade." << endl;
	cout << "Exams Average= " << get_average(student.exam_grades, 3) << endl;
	cout << "Homeworks Average= " << get_average(student.homework_grades, 7) << endl;
	student.grade = get_average(student.exam_grades, 3) * 0.40 + get_average(student.homework_grades, 7)  * 0.60;
	cout << "Grade = " << student.grade << endl;
	return;
}


Jones Shelia
Birthdate:     6 21 1992
ID:            3472
Class:         FR
Major:         CS
Homework Grade: 87.00
Exams:         91.00


Bain Robert
Birthdate:     6 1991 0
ID:            1754
Class:         SO
Major:         CS
Homework Grade: 0.00
Exams:         0.00


77 88
Birthdate:     95 93 0
ID:            86
Class:         78
Major:         83
Homework Grade: 0.00
Exams:         0.00


95 87
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00


 
Birthdate:     0 0 0
ID:            
Class:         
Major:         
Homework Grade: 0.00
Exams:         0.00

Enter first and last name.


data file

LAST NAME	FIRST NAME	BIRTH DATE	ID	CLASS	MAJOR	HOMEWORK SCORES 		EXAM SCORES
Jones		Shelia		06 21 1992	3472	FR	CS	87 89 65 90 91 93 79	91 94 90
Bain		Robert		11 06 1991	1754	SO	CS	77 88 99 95 93 86 78	83 95 87
Smith		Pamela		07 18 1990	1888	SO	CS	87 92 95 92 94 88 89	79 85 89
Hall		Sherry		08 07 1993	7640	SR	BIO	85 89 75 83 91 95 92	91 81 84
Stokes		Jerry		06 25 1990	2311	JR	CS	83 89 85 88 91 93 95	85 95 90
Clayton		Randy		05 21 1992	9077	JR	EE	80 86 95 89 97 83 96	78 83 90
Chancellor	Janet		02 28 1991	2341	SO	CHEM	87 99 95 88 97 90 85	82 88 94
Adams		Mark		04 16 1989	1764	FR	CS	96 97 99 91 93 89 98	95 97 96
Hooten		Lamar		10 31 1988	8734	SO	CS	91 89 77 90 91 90 84	91 85 86
Mintor		Lara		10 31 1993	8734	FR	MATH	88 85 79 93 92 81 86	95 82 89
Last edited on
Have you tried printing the values of a student_record after you read them? You can't really know they've been read unless you've seen them immediately after reading.
Well commenting out L90-94 doesn't help as that messes up the reading of subsequent lines.

You also want to consider having a function to read one record into a student_record. Then you don't need separate code to read the first record and the next 9. You also shouldn't assume that there are 10 records - shouldn't the code read all the records present?
@seeplus the reason why I commented out those lines is because I get a segmentation error and the program does not work at all. So I made them comments.
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
int main(void)
{
        ifstream infile;
        infile.open("/Users/adam/desktop/temp/student_records.txt");
       
        string line;
        student_record *student = new student_record; // Pointer to student_record type
       
        if (!infile)
        {
                cout << "Unable to open the student data file." << endl;
                return 1; // Error code for file open error
        }

        cout << "Student File opened." << endl;
        // Read and ingnore the first line of the file.
        // They are not data lines.

        getline(infile, line);
        
        /*
        // Read in the data for the first student
        infile >> student->firstname >> student->lastname >> student->birthdate.month 
                  >> student->birthdate.day >> student->birthdate.year
                   >> student->ID >> student->year >> student->major;
        
        for (int k = 0; k < 7; k++)
            infile >> student->homework_grades[k];
        
        for (int k = 0; k < 3; k++)
            infile >> student->exam_grades[k];     
        */
        student_record *root=NULL, *new_node;
        
        // making first node
        root=student;
        student->link=NULL;
        
        
        // reading remaining 9 data and making node
        
        for(int i=0;i<10;i++)
        {
                student_record *new_node = new student_record;
                student_record *current_node=root;
                while(current_node->link)                                      // traversing till last so that we can add node there
                {
                        current_node=current_node->link;
                        }
                        
                        infile >> new_node->firstname >> new_node->lastname >> new_node->birthdate.month
                              >> new_node->birthdate.day >> new_node->birthdate.year        // reading data
                               >> new_node->ID >> new_node->year >> new_node->major;
                    
                    
                    for (int k = 0; k < 7; k++)
            		infile >> student->homework_grades[k];
        
        		    for (int k = 0; k < 3; k++)
           		    infile >> student->exam_grades[k];          
                       
                    current_node->link=new_node;       // adding node
                    new_node->link=NULL;
                    
                }
                
                
                // Printing
                
                
                student_record *current_node=root;
                while(current_node)
                {
                print_data(*current_node);
                
                current_node=current_node->link;
                }
        enter_data(root);
        return 0;
}

I attempted to just edit the for loop to read all records I just get a segmentation fault now.
Last edited on
Perhaps:

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

struct Date {
	unsigned int month {};
	unsigned int day {};
	unsigned int year {};
};

struct Student_record {
	string firstname;
	string lastname;
	Date birthdate;
	string year;
	string major;
	string ID;
	double homework_grades[7] {};
	double exam_grades[3] {};
	float grade {};
};

struct Node {
	Student_record sr;
	Node* next {};
};

istream& operator>>(istream& infile, Student_record* student) {
	if (infile) {
		infile >> student->firstname >> student->lastname >> student->birthdate.month
			>> student->birthdate.day >> student->birthdate.year
			>> student->ID >> student->year >> student->major;

		for (size_t k = 0; k < 7; ++k)
			infile >> student->homework_grades[k];

		for (size_t k = 0; k < 3; k++)
			infile >> student->exam_grades[k];
	}

	return infile;
}

ostream& operator<<(ostream& outfile, Student_record* person) {
	outfile << '\n';
	outfile << fixed << setprecision(2) << left;
	outfile << person->firstname << " " << person->lastname << '\n';
	outfile << setw(15) << "Birthdate: " << person->birthdate.month << " " << person->birthdate.day << " " << person->birthdate.year << '\n';
	outfile << setw(15) << "ID: " << person->ID << '\n';
	outfile << setw(15) << "Class: " << person->year << '\n';
	outfile << setw(15) << "Major: " << person->major << '\n';
	outfile << setw(15) << "Homework Average:\n" << setw(15) << " ";

	for (size_t k = 0; k < 7; ++k)
		outfile << person->homework_grades[k] << ' ';

	outfile << "\nExam Average:\n" << setw(15) << " ";

	for (size_t k = 0; k < 3; ++k)
		outfile << person->exam_grades[k] << ' ';

	return outfile << '\n';
}

int main()
{
	ifstream infile ("student_records.txt");

	if (!infile)
		return (cout << "Cannot open file\n"), 1;

	string header;

	getline(infile, header);

	Node* root {};

	for (Node* sr (new Node); infile >> &sr->sr; infile ? sr = new Node: sr)
		if (root == nullptr)
			root = sr;
		else {
			auto cr {root};

			for (; cr->next; cr = cr->next);
			cr->next = sr;
		}

	for (auto sr = root; sr; sr = sr->next)
		cout << &sr->sr << '\n';

	for (auto sr = root; sr; ) {
		const auto t {sr};

		sr = sr->next;
		delete t;
	}
}



Jones Shelia
Birthdate:     6 21 1992
ID:            3472
Class:         FR
Major:         CS
Homework Average:
               87.00 89.00 65.00 90.00 91.00 93.00 79.00
Exam Average:
               91.00 94.00 90.00


Bain Robert
Birthdate:     11 6 1991
ID:            1754
Class:         SO
Major:         CS
Homework Average:
               77.00 88.00 99.00 95.00 93.00 86.00 78.00
Exam Average:
               83.00 95.00 87.00


Smith Pamela
Birthdate:     7 18 1990
ID:            1888
Class:         SO
Major:         CS
Homework Average:
               87.00 92.00 95.00 92.00 94.00 88.00 89.00
Exam Average:
               79.00 85.00 89.00


Hall Sherry
Birthdate:     8 7 1993
ID:            7640
Class:         SR
Major:         BIO
Homework Average:
               85.00 89.00 75.00 83.00 91.00 95.00 92.00
Exam Average:
               91.00 81.00 84.00


Stokes Jerry
Birthdate:     6 25 1990
ID:            2311
Class:         JR
Major:         CS
Homework Average:
               83.00 89.00 85.00 88.00 91.00 93.00 95.00
Exam Average:
               85.00 95.00 90.00


Clayton Randy
Birthdate:     5 21 1992
ID:            9077
Class:         JR
Major:         EE
Homework Average:
               80.00 86.00 95.00 89.00 97.00 83.00 96.00
Exam Average:
               78.00 83.00 90.00


Chancellor Janet
Birthdate:     2 28 1991
ID:            2341
Class:         SO
Major:         CHEM
Homework Average:
               87.00 99.00 95.00 88.00 97.00 90.00 85.00
Exam Average:
               82.00 88.00 94.00


Adams Mark
Birthdate:     4 16 1989
ID:            1764
Class:         FR
Major:         CS
Homework Average:
               96.00 97.00 99.00 91.00 93.00 89.00 98.00
Exam Average:
               95.00 97.00 96.00


Hooten Lamar
Birthdate:     10 31 1988
ID:            8734
Class:         SO
Major:         CS
Homework Average:
               91.00 89.00 77.00 90.00 91.00 90.00 84.00
Exam Average:
               91.00 85.00 86.00


Mintor Lara
Birthdate:     10 31 1993
ID:            8734
Class:         FR
Major:         MATH
Homework Average:
               88.00 85.00 79.00 93.00 92.00 81.00 86.00
Exam Average:
               95.00 82.00 89.00

Topic archived. No new replies allowed.