c++ Program that uses structs and nodes to read data file
Nov 13, 2021 at 8:58pm UTC
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 Nov 14, 2021 at 12:34am UTC
Nov 14, 2021 at 5:49am UTC
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.
Nov 14, 2021 at 10:14am UTC
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?
Nov 14, 2021 at 9:42pm UTC
@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 Nov 14, 2021 at 9:46pm UTC
Nov 15, 2021 at 11:54am UTC
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.