-4

I'm getting an error for Segment fault 11. It will run through the printall()command but seems to fail at the printInvalidEmail command.

I can also input the other classes I have created. I have about 6 different classes and header files for the classes. I'm looking for where to start to troubleshoot this error.

/*
 * roster.cpp
 *
 *  Created on: Jan 9, 2019
 *      Author: kaylasiemon
 */
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include "student.h"
#include "securityStudent.h"
#include "networkStudent.h"
#include "softwareStudent.h"
#include "degree.h"
#include "roster.h"

using namespace std;

roster::roster() {
}

roster::~roster() {
}

void roster::add(string studentID, string firstName, string lastName, string emailAddress, int age, int daysInCourse1, int daysInCourse2, int daysInCourse3, degree d){
    int courseDays[] = {daysInCourse1, daysInCourse2, daysInCourse3};
    if (d == degree::SECURITY)
        classRosterArray[iindex++] = new securityStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);

    if (d == degree::SOFTWARE)
        classRosterArray[iindex++] = new softwareStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);

    if (d == degree::NETWORK)
        classRosterArray[iindex++] = new networkStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);
}

void roster::remove(string studentID){
    bool removeStudent = false;
    for(int i = 0; i < 5; i++){
        if (classRosterArray[i] != NULL) {
            if(studentID == classRosterArray[i] ->getID()){
                classRosterArray[i] = nullptr;
                removeStudent = true;
            }
        }
    }
    if (removeStudent == false)
        cout << "Student ID invalid. No one to remove";
}

void roster::printAll(){
    cout << "Roster:" << endl;
    for (int i = 1; i < 6; i++)
        classRosterArray[i] -> print();
}

void roster::printByDegreeProgram(int degreeProgram){
    cout << "Displaying Roster by Degree Type:" << endl;
    degree deg1;
    if (degreeProgram == 0)
        deg1 = degree::SECURITY;
    if (degreeProgram == 1)
        deg1 = degree::NETWORK;
    if (degreeProgram == 2)
        deg1 = degree::SOFTWARE;
    for (int i = 1; i < 6; i++){
        if (deg1 == classRosterArray[i]->getDegreeProgram())
            classRosterArray[i] -> print();
    }
}

void roster::printDaysInCourse(string studentID){
    int average;
    for (int i = 1; i < 6; i++){
        if (classRosterArray[i] ->getID() == studentID){
            average = (classRosterArray[i]->getCourseDays()[0] + classRosterArray[i]->getCourseDays()[1] + classRosterArray[i]->getCourseDays()[2]) / 3;
            cout << average << endl;
        }
    }
}

void roster::printInvalidEmails(){
    cout << "invalid email addresses:" << endl;
    for (int i = 0; i < 5; i++){
        bool atSign = false;
        bool space = false;
        bool period = false;
        string email;
        email = classRosterArray[i] ->getemail();
        for (char &letter:email){
            if (letter == '@')
                atSign = true;
            if (letter == ' ')
                space = true;
            if (letter == '.')
                period = true;
        }
        if (atSign == false || space == false || period == false)
            cout << classRosterArray[i] ->getemail() << endl;
    }
}

int main(){
    const string studentData[] ={   "A1,John,Smith,John1989@gm ail.com,20,30,35,40,SECURITY",
                                    "A2,Suzan,Erickson,Erickson_1990@gmailcom,19,50,30,40,NETWORK",
                                    "A3,Jack,Napoli,The_lawyer99yahoo.com,19,20,40,33,SOFTWARE",
                                    "A4,Erin,Black,Erin.black@comcast.net,22,50,58,40,SECURITY",
                                    "A5,Kayla,Siemon,ksiemon@wgu.edu,24,30,33,29,SOFTWARE"};

    roster classRoster;

    cout << "Scripting and Programming - Applications – C867" << endl << "Kayla Siemon" << endl <<"#000736769" << endl;
    degree degreepath;
    for (int i = 0; i < 5; i++){
        stringstream studentlist(studentData[i]);
        vector<string> results;

        while(studentlist.good()){
            string temp;
            getline(studentlist, temp, ',');
            results.push_back(temp);
        }
        if (results[8] == "SECURITY")
            degreepath = degree::SECURITY;
        if (results[8] == "NETWORK")
            degreepath = degree::NETWORK;
        if (results[8] == "SOFTWARE")
            degreepath = degree::SOFTWARE;
        classRoster.add(results[0], results[1], results[2], results[3], stoi(results[4]), stoi(results[5]), stoi(results[6]), stoi(results[7]), degreepath);
    }
    classRoster.printAll();
    classRoster.printInvalidEmails();
        classRoster.printDaysInCourse("A1");
    classRoster.printByDegreeProgram(SOFTWARE);
    classRoster.remove("A3");
    classRoster.remove("A3");

     return 0;
}
Dale K
  • 16,372
  • 12
  • 37
  • 62
kayla
  • 1

1 Answers1

3

This is a good opportunity to develop your debugging skills. The first thing you want to do is figure exactly which line of code is triggering the crash. You can do that with a debugger (by stepping through the code), or if you prefer, you can just instrument your code manually. For example, if you think the crash is occurring within the printInvalidEmail() method, you can narrow it down to a particular line, by temporarily adding debug-output lines to the method, like this:

void roster::printInvalidEmails(){
    cout << "invalid email addresses:" << endl;
    for (int i = 0; i < 5; i++){
cout << "X1 " << i << endl;
        bool atSign = false;
        bool space = false;
        bool period = false;
cout << "X2 " << endl;
        string email;
cout << "X3 " << endl;
        email = classRosterArray[i] ->getemail();
cout << "X4 " << endl;
        for (char &letter:email){
cout << "X5 " << letter << endl;
            if (letter == '@')
                atSign = true;
            if (letter == ' ')
                space = true;
            if (letter == '.')
                period = true;
        }
cout << "X6" << endl;
        if (atSign == false || space == false || period == false)
        {
cout << "X7" << endl;
            cout << classRosterArray[i] ->getemail() << endl;
        }
cout << "X8" << endl;
    }
cout << "X9" << endl;
}

Note that I've inserted a lot of lines like cout << "X1" << endl;, each printing a unique string so I can easily tell them apart. Now when you run your program, you'll get a lot more output, but the main thing to look at is the last line of text your program outputs, just before it crashes -- the code that is causing the crash is likely directly after the line that output that text.

Find that line, and it will (hopefully) give you an idea about why that line might be crashing -- for example, if the last line of text output you saw was "X3", and you didn't see "X4" printed afterwards, then you can be pretty sure that the line email = classRosterArray[i]->getemail(); caused the crash ... and a likely reason for that would be that classRosterArray[i] is a NULL, or otherwise invalid pointer (and therefore a crash occurs when you try to dereference it to call getemail()) -- then you need to track down the various places that set entries in classRosterArray to figure out why they are not setting it correctly. (Or alternatively, it could be that there is a bug inside the getmail() method, and the program is crashing inside there -- in which case you could add more debug output inside that method to figure out where and why)

Once you've figure out what is causing the crash, and fixed it, you can then go back and remove all the temporary debug-output lines again. (Note that I've deliberately left all the temporary cout calls un-indented, that way they clearly stick out from the "real" code and it's easy to go back and quickly delete them when you're done debugging)

Jeremy Friesner
  • 57,675
  • 12
  • 103
  • 196