Hello,

I am writing a program that reads in data from a text file and puts it into a linked list. Certain variables are read in only if the "officeHeld" number is a particular number, otherwise the variable is set to 0. When I run this through Visual Studio, I get a blank black screen with nothing on it. When I run it through our university's unix, I get "segmentation fault". I am not sure where the error is here and I'm at a loss. Any help or suggestion would be overwhelmingly appreciated. I'm attaching the code as well as some of the text file information!

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

ifstream inputFile;

struct PublicOfficial
{
    string name;
    string birthState;
    int officeHeld;
    int order;
    int presFirstTerm;
    int presLastTerm;
    int viceFirstTerm;
    int viceLastTerm;
    PublicOfficial *next;
};

void LoadList(PublicOfficial *&head);
void addOfficial(PublicOfficial *&head, PublicOfficial *newNode);
void printOfficials(PublicOfficial *head);

int main()
{
    PublicOfficial *head = NULL;
    PublicOfficial *newNode = NULL;
    LoadList(head);
    printOfficials(head);
    system("pause");
    return 0;
}

void LoadList(PublicOfficial *&head)
{
    PublicOfficial *newNode;
    inputFile.open("officials.txt");
    while (!inputFile.eof())
    {
        newNode = new PublicOfficial;
        newNode->next = NULL;
        getline(inputFile, newNode->name);
        getline(inputFile, newNode->birthState);
        inputFile >> newNode->officeHeld;
        if (newNode->officeHeld == 1 || newNode ->officeHeld == 3)
        {
            inputFile >> newNode->order;
            inputFile >> newNode->presFirstTerm;
            inputFile >> newNode->presLastTerm;
        }
        else
        {
            newNode->order = 0;
            newNode->presFirstTerm = 0;
            newNode->presLastTerm = 0;
        }
        if(newNode->officeHeld == 2 || newNode-> officeHeld == 3)
        {
            inputFile >> newNode->viceFirstTerm;
            inputFile >> newNode->viceLastTerm;
        }
        else
        {
            newNode->viceFirstTerm=0;
            newNode->viceLastTerm=0;
        }
        addOfficial(head, newNode);
    }
    inputFile.close();
}

void addOfficial(PublicOfficial *&head, PublicOfficial *newNode)
{
    if (!head)
    {
        head = newNode;
    }
    else
    {
        newNode->next = head;
        head = newNode;
    }
}

void printOfficials(PublicOfficial *head)
{
    PublicOfficial *tptr = head;

    if (!tptr)
    {
        cout << "The list is empty";
    }
    else{

        while (tptr)
        {
            cout << setw(7) << tptr->birthState << setw(12) << tptr->officeHeld <<
                setw(12) << tptr->order << setw(12) << tptr->presFirstTerm << setw(12)
                << tptr->presLastTerm << setw(12) << tptr->viceFirstTerm << setw(12) << tptr->viceLastTerm;

            tptr= tptr->next;
        }
    }
    cout << endl;
}

Here is a sample piece of the text document (it's a long one so I'm only including a sample, but if I can get it to read even one in, then it's working correctly)

Text File:

WALLACE, HENRY
IOWA
2
33
1941
1945
WASHINGTON, GEORGE
VIRGINIA
1
01
1789
1797
WHEELER, WILLIAM
NEW YORK
2
19
1877
1881
WILSON, HENRY
NEW HAMPSHIRE
2
18
1873
1877

You should use Visual Studio to debug through program and see where the problem is. The debugger will know if you're trying to access memory that doesn't belong to your program. Or you can always use printf() statements to see which ones output or not to debug the program.

Segmentation fault is the result of accessing a value outside the range of the array.

ie.

int numbers[100];
numbers[121] = 560;    // segmentation fault

On another note, on line 33 you should avoid using system calls like system("pause"). You can just use cin.get() to pause and wait until the users presses a key.

I did run it through VS with a debugger, it came up with no errors or warnings.

I have fixed the problem with the segmentation. I was writing code to add the nodes to the top of the list, not the end like I wanted.

That being said, I'm still having problems with my addOfficials function. For some reason, when it hits the 'else' part, it doesn't add subsequent nodes. The 'if' statements works - adding the first node to the head, but after that it doesn't add correctly, and when I call my printAll function, it only displays the first node.

Here is my updated code. Any suggestions would be great, I've been looking at example codes and my code looks the same, so I'm rather confused.

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

ifstream inputFile;

struct PublicOfficial
{
    string name;
    string birthState;
    int officeHeld;
    int presOrder;
    int presFirstTerm;
    int presLastTerm;
    int viceOrder;
    int viceFirstTerm;
    int viceLastTerm;
    PublicOfficial *next;
};

void LoadList(PublicOfficial *&head);
void addOfficial(PublicOfficial *&head, PublicOfficial *newNode);
void printOfficials(PublicOfficial *head);

int main()
{
    PublicOfficial *head = NULL;
    PublicOfficial *newNode = NULL;
    LoadList(head);
    printOfficials(head);
    system("pause");
    return 0;
}

void LoadList(PublicOfficial *&head)
{
    PublicOfficial *newNode;
    inputFile.open("officials.txt");
    while (!inputFile.eof())
    {
        newNode = new PublicOfficial;
        newNode->next = NULL;
        getline(inputFile, newNode->name);
        getline(inputFile, newNode->birthState);
        inputFile >> newNode->officeHeld;
        if (newNode->officeHeld == 1 || newNode ->officeHeld == 3)
        {
            inputFile >> newNode->presOrder;
            inputFile >> newNode->presFirstTerm;
            inputFile >> newNode->presLastTerm;
        }
        else
        {
            newNode->presOrder = 0;
            newNode->presFirstTerm = 0;
            newNode->presLastTerm = 0;
        }
        if(newNode->officeHeld == 2 || newNode-> officeHeld == 3)
        {
            inputFile >> newNode->viceOrder;
            inputFile >> newNode->viceFirstTerm;
            inputFile >> newNode->viceLastTerm;
        }
        else
        {
            newNode->viceOrder = 0;
            newNode->viceFirstTerm=0;
            newNode->viceLastTerm=0;
        }
        inputFile.ignore();
        addOfficial(head, newNode);
    }
    inputFile.close();
}

void addOfficial(PublicOfficial *&head, PublicOfficial *newNode)
{
    PublicOfficial *tptr = NULL;

    if (!head)
    {
        head = newNode;
    }
    else
    {
        tptr = head;
        while (tptr->next)
        {
        tptr = tptr->next;
        tptr->next = newNode;
        }
    }
}

void printOfficials(PublicOfficial *head)
{
    PublicOfficial *tptr = head;

    if (!tptr)
    {
        cout << "The list is empty";
    }
    else{

        while (tptr)
        {
            cout << setw(7) << tptr->name << setw(12) << tptr->birthState << setw(12) << tptr->officeHeld <<
                setw(12) << tptr->presOrder << setw(12) << tptr->presFirstTerm << setw(12)
                << tptr->presLastTerm << setw(12) << tptr->viceOrder << setw(12) << tptr->viceFirstTerm << setw(12) << tptr->viceLastTerm;

            tptr = tptr->next;
        }
    }
}
else
{
    tptr = head;
    while (tptr->next)
    {
        tptr = tptr->next;
        tptr->next = newNode;
    }
}

Assuming that you have already entered the first record, the Wallace Henry record and you are about to enter the second record (Washington, George record). Prior to entering the second record, the tptr->next would be pointing to NULL. So, the second and succeeding records will not be added since the logic does not enter into the while loop in order to add the next record.

If you want to add to the end, you can use a for loop:

// traverse through the list until we reach the last node
for (current = head; current->next; current = current->next) {
   ;
}

current->next = new_node;
This article has been dead for over six months. Start a new discussion instead.