I need help with my c++ program. Everything compiles perfectly fine but when I r
ID: 3799057 • Letter: I
Question
I need help with my c++ program. Everything compiles perfectly fine but when I run the program and try to add a course, I get a segment fault error and i cant figure out why this is happening. I am using the void College::add(course c) function in the college.cc file to add the course so the error may be there but im not sure. Please find out why I am getting the seg fault error and show me how to correct the error. Below is all of my code:
collegemain.cc below
---------------------------------------------------------------
#include <iostream>
#include <fstream>
#include <string>
#include "course.h"
#include "node.h"
#include "college.h"
using namespace std;
// This function displays the menu and returns the user's choice
int menu();
int main(){
int choice;
course c;
string coursename;
ifstream fin;
ofstream fout;
string username,filename, fullname;
cout<<"Welcome to Your College Course Management. ";
cout<<"Begin by entering your username: ";
getline(cin,username);
filename = username + ".txt";
cout<<"Now Enter Your Full name:";
while(cin.peek()==' ')cin.ignore();
getline(cin,fullname);
// Here you are calling a constructor that takes a string as a
// parameter
College mycollege(fullname);
fin.open(filename.c_str());
if(!fin.fail())
mycollege.load(fin);
fin.close();
choice = menu();
while(choice != 0){
switch(choice){
case 1:
cout<<"Enter a new course that you have taken. ";
cin>>c;
mycollege.add(c);
break;
case 2:
mycollege.display(cout);
break;
case 3:
cout<<"Enter the name/course number of the course you ";
cout<<"need to remove. ";
cin>>coursename;
mycollege.remove(coursename);
break;
case 4:
cout<<"Total hours = "<<mycollege.hours();
break;
case 5:
cout<<"Your current GPA = "<<mycollege.gpa();
break;
case 6:{
College acopy(mycollege);
cout<<"Enter one a course you would like to remove if you could. ";
cin>>coursename;
acopy.remove(coursename);
cout<<"This would make your GPA:"<<acopy.gpa();
cout<<"And your courselist would look like.";
acopy.display(cout);
cout<<"But your GPA is still really: "<<mycollege.gpa();
break;
} // the copy goes out of scope here - destructor runs
case 0:
cout<<"Thank you for using course management. ";
break;
default:
cout<<"Not an option. ";
break;
} //bottom of the switch
choice = menu();
}// bottom or the while loop, which is a senteniel loop
fout.open(filename.c_str());
if(!fout.fail())
mycollege.save(fout);
else
cout<<"Problem with saving data! ";
fout.close();
return 0;
}
int menu(){
int choice;
cout<<"Choose from the following options: ";
cout<<"1) Add an additional course to your record. ";
cout<<"2) Display all the courses taken thus far. ";
cout<<"3) Remove a course from your college record. ";
cout<<"4) Display the total hours thus far completed. ";
cout<<"5) Display your current GPA. ";
cout<<"6) Test your copy constructor. ";
cout<<"0) Quit - saving all changes. ";
cin>>choice;
return choice;
}
college.cc below
--------------------------------------------------
#include "college.h"
using namespace std;
College::~College(){
node* c = head_ptr;
node* rm;
while (c != NULL)
rm = c;
c = c->link();
delete rm;
}
College::College(const College& source){
if(source.head_ptr == NULL)
head_ptr = NULL;
else {
head_ptr = new node(source.head_ptr->data());
const node* sptr = source.head_ptr->link();
node* dptr = head_ptr;
while (sptr != NULL) {
dptr->set_link(new node(sptr->data()));
dptr = dptr->link();
sptr = sptr->link();
}
}
}
void College::operator =(const College& source){
if(source.head_ptr == NULL)
head_ptr = NULL;
else {
head_ptr = new node(source.head_ptr->data());
const node* sptr = source.head_ptr->link();
node* dptr = head_ptr;
while (sptr != NULL) {
dptr->set_link(new node(sptr->data()));
dptr = dptr->link();
sptr = sptr->link();
}
}
}
//mutators
void College::add(course c) {
node* inserter = new node;
inserter->set_data(c);
if (inserter->data() < head_ptr->data()) {
node* tmp; //if new course is < head, make it new head
tmp = head_ptr;
head_ptr = inserter;
head_ptr->set_link(tmp);
} else {
node* c; //walk through and add course node
for (c = head_ptr; (c->link() != NULL) && (inserter->data() > c->link()->data()); c = c->link()){} //walk to node before insert point
if (c->link() == NULL) {
c->set_link(inserter); //if being set to last item
return; //get out of function
}
inserter->set_link(c->link());
c->set_link(inserter);
}
}
void College::remove(const std::string& target){
node* cursor = head_ptr;
node* remove_ptr;
if (cursor->data().get_course_number() == target){ //if removing head node
remove_ptr = head_ptr;
head_ptr = head_ptr->link();
delete remove_ptr;
cout << "target found at begining of list and removed! ";
return;
}
while (cursor->link() != NULL && cursor->link()->data().get_course_number() != target) //rm'd cursro ->link() check
(cursor = cursor->link());
if (cursor->link()->data().get_course_number() == target) {
remove_ptr = cursor->link();
cursor->set_link( cursor->link()->link() );
delete remove_ptr;
cout << "target found and removed! ";
return;
}
cout << "target not found ";
}
istream& College::load(istream& inp) {
node* inserter;
node* tail; //holds last node in list
course data;
while (inp && inp.peek() != EOF) {
while (inp.peek()==' ') inp.ignore();
if(head_ptr == NULL) {
data.input(inp); //start node list if first item
head_ptr = new node;
head_ptr->set_data(data);
tail = head_ptr;
} else {
data.input(inp); //add to proper place on list
inserter = new node;
inserter->set_data(data);
if ((head_ptr->link() == NULL) && (inserter->data() < head_ptr->data())){
inserter->set_link(head_ptr); //if new 2nd node < head //make new node link point to head
head_ptr = inserter; // turn head into the new first item
} else if ((head_ptr->link() == NULL) && (inserter->data() > head_ptr->data())) {
head_ptr->set_link(inserter);//if 2nd new node is larger than head
tail = head_ptr->link();
} else {
if (inserter->data() < head_ptr->data()) {
node* tmp; //if new course is < head, make it new head
tmp = head_ptr;
head_ptr = inserter;
head_ptr->set_link(tmp);
} else if (inserter->data() > tail->data()) {
tail->set_link(inserter); //add to end of list
tail = inserter;
} else {
node* c; //walk through and add course node
for (c = head_ptr; inserter->data() > c->link()->data(); c = c->link()){} //walk to node before insert point
inserter->set_link(c->link());
c->set_link(inserter);
}
}
}
}
}
//accessors
void College::display(ostream& outp) const{
for (node* j = head_ptr; j != NULL; j = j->link())
j->data().output(outp);
}
int College::hours() const{
int sum(0);
for (node* j = head_ptr; j != NULL; j = j->link()){
sum += j->data().get_hours();
}
return sum;
}
double College::gpa() const{
double finalgpa(0);
double sum(0);
//double t_hrs(0);
for (node* i = head_ptr; i != NULL; i = i->link()){
sum += (i->data().get_number_grade() * i->data().get_hours());
//t_hrs += i->get_hours();
}
finalgpa = (sum / hours());
return finalgpa;
// point value is number_grade * hrs per course
// then sum points, divide by total hours
}
ostream& College::save(ostream& fout){
for (node* j = head_ptr; j != NULL; j = j->link())
j->data().output(fout);
return fout;
}
college.h below
-------------------------------------------
#ifndef COLLEGE_H
#define COLLEGE_H
#include "node.h"
#include<cstdlib>
#include<cstdio>
class College {
public:
//constructors
College() {student_name = "defaultname"; head_ptr = NULL;}
College(std::string name) {student_name = name; head_ptr = NULL;}
//need big 3
~College();
College(const College& source);
void operator =(const College& source);
//mutators
void add(course c);
void remove(const std::string& target);
std::istream& load(std::istream& inp);
std::ostream& save(std::ostream& fout);
//accessors
void display(std::ostream& outp) const;
int hours() const;
double gpa() const;
private:
std::string student_name;
node* head_ptr;
};
#endif
course.cc below
------------------------------------------------
#include "course.h"
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
course::course(){
hours = 0.0;
}
void course::input(std::istream& ins){
if(ins == cin){
cout<<"Course Number: ";
if(ins.peek() == ' ') ins.ignore();
getline(ins, course_number);
if(ins.eof()) return;
cout<<"Grade received: ";
getline(ins, grade);
grade[0] = toupper(grade[0]);
if(ins.eof()) return;
cout<<"Credit hours: ";
ins>>hours;
upper_course(); // makes all lower case letters into caps
}
else{
if(ins.peek() == ' ') ins.ignore();
getline(ins, course_number);
if(ins.eof()) return;
getline(ins, grade);
grade[0] = toupper(grade[0]);
if(ins.eof()) return;
ins>>hours;
}
}
void course::output(std::ostream& outs)const{
if(outs == cout){
outs<<"Course Number:"<<course_number<<endl;
outs<<"Grade received:"<<grade<<endl;
outs<<"Credit hours:"<<setprecision(2)<<hours<<endl;
}
else{
outs<<course_number<<endl;
outs<<grade<<endl;
outs<<setprecision(2)<<hours<<endl;
}
}
double course::get_number_grade()const{
if(grade == "A") return 4.0;
if(grade == "A-") return 3.667;
if(grade == "B+") return 3.333;
if(grade == "B") return 3.0;
if(grade == "B-") return 2.667;
if(grade == "C+") return 2.333;
if(grade == "C") return 2.0;
if(grade == "C-") return 1.667;
if(grade == "D+") return 1.333;
if(grade == "D") return 1.0;
if(grade == "D-") return 0.667;
if(grade == "F") return 0.0;
else return 0;
}
void course::set_course(std::string num, std::string grad, double hrs){
course_number = num;
grade = grad;
hours = hrs;
}
istream& operator >>(istream& ins, course& c){
c.input(ins);
return ins;
}
ostream& operator <<(ostream& outs, const course& c){
c.output(outs);
return outs;
}
void course::upper_course(){
for(int i =0; i<course_number.length(); ++i)
course_number[i] = toupper(course_number[i]);
}
course.h below
---------------------------------------------------
#include<iostream>
#include<string>
#ifndef COURSE_H
#define COURSE_H
class course{
public:
course();
// Input and output functions
void input(std::istream& ins);
void output(std::ostream& outs)const;
// accessor functions
std::string get_course_number()const{
return course_number;
}
std::string get_grade()const{
return grade;
}
double get_hours()const{
return hours;
}
double get_number_grade()const;
// mutator function
void set_course(std::string num, std::string grad, double hrs);
//COMPARISON OPERATORS - ORDERS LISTS BY THEIR COURSE NUMBERS
bool operator < (const course& c)const{return course_number < c.course_number;}
bool operator <= (const course& c)const{return course_number <= c.course_number;}
bool operator > (const course& c)const{return course_number > c.course_number;}
bool operator >= (const course& c)const{return course_number >= c.course_number;}
bool operator == (const course& c)const{return course_number == c.course_number;}
bool operator != (const course& c)const{return course_number != c.course_number;}
private:
void upper_course();
std::string course_number;
std::string grade;
double hours;
};
std::istream& operator >>(std::istream& ins, course& c);
std::ostream& operator <<(std::ostream& outs, const course& c);
#endif
node.h below
------------------------------------------
#ifndef NODE_H
#define NODE_H
#include "course.h"
class node{
public:
typedef course value_type;
// Universal constructor
node(value_type d = value_type(), node *l = NULL)
{data_field = d; link_field = l;}
// Mutator functions
void set_data(value_type d)
{data_field = d;}
void set_link(node *l)
{link_field = l;}
// Accessor functions
value_type data() const
{return data_field;}
node* link()
{return link_field;}
const node* link() const
{return link_field;}
private:
value_type data_field;
node* link_field;
};
#endif
I aplogize that there is so much but I just didnt want to leave anything out just in case. Thank you
Explanation / Answer
A)
#include <iostream>
#include <fstream>
#include <string>
#include "course.h"
#include "node.h"
#include "college.h"
using namespace std;
int menu();
int main(){
int choice;
course c;
string coursename;
ifstream fin;
ofstream fout;
string username,filename, fullname;
cout<<"Welcome to Your College Course Management. ";
cout<<"Begin by entering your username: ";
getline(cin,username);
filename = username + ".txt";
cout<<"Now Enter Your Full name:";
while(cin.peek()==' ')cin.ignore();
getline(cin,fullname);
College mycollege(fullname);
fin.open(filename.c_str());
if(!fin.fail())
mycollege.load(fin);
fin.close();
choice = menu();
while(choice != 0){
switch(choice){
case 1:
cout<<"Enter a new course that you have taken. ";
cin>>c;
mycollege.add(c);
break;
case 2:
mycollege.display(cout);
break;
case 3:
cout<<"Enter the name/course number of the course you ";
cout<<"need to remove. ";
cin>>coursename;
mycollege.remove(coursename);
break;
case 4:
cout<<"Total hours = "<<mycollege.hours();
break;
case 5:
cout<<"Your current GPA = "<<mycollege.gpa();
break;
case 6:{
College acopy(mycollege);
cout<<"Enter one a course you would like to remove if you could. ";
cin>>coursename;
acopy.remove(coursename);
cout<<"This would make your GPA:"<<acopy.gpa();
cout<<"And your courselist would look like.";
acopy.display(cout);
cout<<"But your GPA is still really: "<<mycollege.gpa();
break;
}
case 0:
cout<<"Thank you for using course management. ";
break;
default:
cout<<"Not an option. ";
break;
}
choice = menu();
}
fout.open(filename.c_str());
if(!fout.fail())
mycollege.save(fout);
else
cout<<"Problem with saving data! ";
fout.close();
return 0;
}
int menu(){
int choice;
cout<<"Choose from the following options: ";
cout<<"1) Add an additional course to your record. ";
cout<<"2) Display all the courses taken thus far. ";
cout<<"3) Remove a course from your college record. ";
cout<<"4) Display the total hours thus far completed. ";
cout<<"5) Display your current GPA. ";
cout<<"6) Test your copy constructor. ";
cout<<"0) Quit - saving all changes. ";
cin>>choice;
return choice;
}
#include "college.h"
using namespace std;
College::~College(){
node* c = head_ptr;
node* rm;
while (c != NULL)
rm = c;
c = c->link();
delete rm;
}
College::College(const College& source){
if(source.head_ptr == NULL)
head_ptr = NULL;
else {
head_ptr = new node(source.head_ptr->data());
const node* sptr = source.head_ptr->link();
node* dptr = head_ptr;
while (sptr != NULL) {
dptr->set_link(new node(sptr->data()));
dptr = dptr->link();
sptr = sptr->link();
}
}
}
void College::operator =(const College& source){
if(source.head_ptr == NULL)
head_ptr = NULL;
else {
head_ptr = new node(source.head_ptr->data());
const node* sptr = source.head_ptr->link();
node* dptr = head_ptr;
while (sptr != NULL) {
dptr->set_link(new node(sptr->data()));
dptr = dptr->link();
sptr = sptr->link();
}
}
}
void College::add(course c) {
node* inserter = new node;
inserter->set_data(c);
if (inserter->data() < head_ptr->data()) {
node* tmp; //if new course is < head, make it new head
tmp = head_ptr;
head_ptr = inserter;
head_ptr->set_link(tmp);
} else {
node* c; //walk through and add course node
for (c = head_ptr; (c->link() != NULL) && (inserter->data() > c->link()->data()); c = c->link()){} //walk to node before insert point
if (c->link() == NULL) {
c->set_link(inserter); //if being set to last item
return; //get out of function
}
inserter->set_link(c->link());
c->set_link(inserter);
}
}
void College::remove(const std::string& target){
node* cursor = head_ptr;
node* remove_ptr;
if (cursor->data().get_course_number() == target){
remove_ptr = head_ptr;
head_ptr = head_ptr->link();
delete remove_ptr;
cout << "target found at begining of list and removed! ";
return;
}
while (cursor->link() != NULL && cursor->link()->data().get_course_number() != target) //rm'd cursro ->link() check
(cursor = cursor->link());
if (cursor->link()->data().get_course_number() == target) {
remove_ptr = cursor->link();
cursor->set_link( cursor->link()->link() );
delete remove_ptr;
cout << "target found and removed! ";
return;
}
cout << "target not found ";
}
istream& College::load(istream& inp) {
node* inserter;
node* tail;
course data;
while (inp && inp.peek() != EOF) {
while (inp.peek()==' ') inp.ignore();
if(head_ptr == NULL) {
data.input(inp);
head_ptr = new node;
head_ptr->set_data(data);
tail = head_ptr;
} else {
data.input(inp);
inserter = new node;
inserter->set_data(data);
if ((head_ptr->link() == NULL) && (inserter->data() < head_ptr->data())){
inserter->set_link(head_ptr); //if new 2nd node < head //make new node link point to head
head_ptr = inserter; // turn head into the new first item
} else if ((head_ptr->link() == NULL) && (inserter->data() > head_ptr->data())) {
head_ptr->set_link(inserter);//if 2nd new node is larger than head
tail = head_ptr->link();
} else {
if (inserter->data() < head_ptr->data()) {
node* tmp; //if new course is < head, make it new head
tmp = head_ptr;
head_ptr = inserter;
head_ptr->set_link(tmp);
} else if (inserter->data() > tail->data()) {
tail->set_link(inserter); //add to end of list
tail = inserter;
} else {
node* c; //walk through and add course node
for (c = head_ptr; inserter->data() > c->link()->data(); c = c->link()){} //walk to node before insert point
inserter->set_link(c->link());
c->set_link(inserter);
}
}
}
}
}
void College::display(ostream& outp) const{
for (node* j = head_ptr; j != NULL; j = j->link())
j->data().output(outp);
}
int College::hours() const{
int sum(0);
for (node* j = head_ptr; j != NULL; j = j->link()){
sum += j->data().get_hours();
}
return sum;
}
double College::gpa() const{
double finalgpa(0);
double sum(0);
t_hrs(0);
for (node* i = head_ptr; i != NULL; i = i->link()){
sum += (i->data().get_number_grade() * i->data().get_hours());
t_hrs += i->get_hours();
}
finalgpa = (sum / hours());
return finalgpa;
}
ostream& College::save(ostream& fout){
for (node* j = head_ptr; j != NULL; j = j->link())
j->data().output(fout);
return fout;
}
#ifndef COLLEGE_H
#define COLLEGE_H
#include "node.h"
#include<cstdlib>
#include<cstdio>
class College {
public:
College() {student_name = "defaultname"; head_ptr = NULL;}
College(std::string name) {student_name = name; head_ptr = NULL;}
~College();
College(const College& source);
void operator =(const College& source);
void add(course c);
void remove(const std::string& target);
std::istream& load(std::istream& inp);
std::ostream& save(std::ostream& fout);
//accessors
void display(std::ostream& outp) const;
int hours() const;
double gpa() const;
private:
std::string student_name;
node* head_ptr;
};
#endif
#include "course.h"
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
course::course(){
hours = 0.0;
}
void course::input(std::istream& ins){
if(ins == cin){
cout<<"Course Number: ";
if(ins.peek() == ' ') ins.ignore();
getline(ins, course_number);
if(ins.eof()) return;
cout<<"Grade received: ";
getline(ins, grade);
grade[0] = toupper(grade[0]);
if(ins.eof()) return;
cout<<"Credit hours: ";
ins>>hours;
upper_course();
}
else{
if(ins.peek() == ' ') ins.ignore();
getline(ins, course_number);
if(ins.eof()) return;
getline(ins, grade);
grade[0] = toupper(grade[0]);
if(ins.eof()) return;
ins>>hours;
}
}
void course::output(std::ostream& outs)const{
if(outs == cout){
outs<<"Course Number:"<<course_number<<endl;
outs<<"Grade received:"<<grade<<endl;
outs<<"Credit hours:"<<setprecision(2)<<hours<<endl;
}
else{
outs<<course_number<<endl;
outs<<grade<<endl;
outs<<setprecision(2)<<hours<<endl;
}
}
double course::get_number_grade()const{
if(grade == "A") return 4.0;
if(grade == "A-") return 3.667;
if(grade == "B+") return 3.333;
if(grade == "B") return 3.0;
if(grade == "B-") return 2.667;
if(grade == "C+") return 2.333;
if(grade == "C") return 2.0;
if(grade == "C-") return 1.667;
if(grade == "D+") return 1.333;
if(grade == "D") return 1.0;
if(grade == "D-") return 0.667;
if(grade == "F") return 0.0;
else return 0;
}
void course::set_course(std::string num, std::string grad, double hrs){
course_number = num;
grade = grad;
hours = hrs;
}
istream& operator >>(istream& ins, course& c){
c.input(ins);
return ins;
}
ostream& operator <<(ostream& outs, const course& c){
c.output(outs);
return outs;
}
void course::upper_course(){
for(int i =0; i<course_number.length(); ++i)
course_number[i] = toupper(course_number[i]);
}
course.h below
#include<iostream>
#include<string>
#ifndef COURSE_H
#define COURSE_H
class course{
public:
course();
void input(std::istream& ins);
void output(std::ostream& outs)const;
std::string get_course_number()const{
return course_number;
}
std::string get_grade()const{
return grade;
}
double get_hours()const{
return hours;
}
double get_number_grade()const;
void set_course(std::string num, std::string grad, double hrs);
bool operator < (const course& c)const{return course_number < c.course_number;}
bool operator <= (const course& c)const{return course_number <= c.course_number;}
bool operator > (const course& c)const{return course_number > c.course_number;}
bool operator >= (const course& c)const{return course_number >= c.course_number;}
bool operator == (const course& c)const{return course_number == c.course_number;}
bool operator != (const course& c)const{return course_number != c.course_number;}
private:
void upper_course();
std::string course_number;
std::string grade;
double hours;
};
std::istream& operator >>(std::istream& ins, course& c);
std::ostream& operator <<(std::ostream& outs, const course& c);
#endif
#ifndef NODE_H
#define NODE_H
#include "course.h"
class node{
public:
typedef course value_type;
node(value_type d = value_type(), node *l = NULL)
{data_field = d; link_field = l;}
void set_data(value_type d)
{data_field = d;}
void set_link(node *l)
{link_field = l;}
value_type data() const
{return data_field;}
node* link()
{return link_field;}
const node* link() const
{return link_field;}
private:
value_type data_field;
node* link_field;
};
end
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.