Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Bookmark I need help with my c++ program. Everything compiles perfectly fine but

ID: 3799820 • Letter: B

Question

Bookmark

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. Please mark what you have changed. Thank you

Explanation / Answer

I am explaining the error. You will be able to correct it.

When you are alling the add function from the switch case of main function, then you are taking the name of course as string and passing to the add function. but the input argument of add function is an object of type course. Hence, there is the error. Before calling the add function, create an object of course with the user input course name and then pass that object as argument to the add function.

Hope it will help you solve the error.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote