lundi 30 octobre 2017

Program crashes when pointer to value of a struct is accessed, Even after it has been given a value

I'm completely stumped by the issue I'm having. I have to write a program that creates, sorts, and modifies a linked list, there is also a sub list that consists of the even values of the list. The issue I'm having is when I add an even value to the list, then try to print the even list in descending order. It appears that when I place the value into the list, the variable that represents a pointer to the previous even in the list is not set. Even though i can see exactly when I set it to a value, if I try to access that value, the program crashes. I apologize if my code is sort of hard to follow. But I believe the problem to be somewhere inside of the addInt() method, inside the else if statement, I've marked the area. Any help would be appreciated, thanks.

    /*
     * Main.cpp
     * Author: Austin Johanningsmeier
     * Description: This program creates, stores, and modifys a linked list of integer values
     *  Created on: Oct 24, 2017
     */

    #include <iostream>
    #include <string>
    #include <fstream>
    using namespace std;

    /*
     * sortInput()
     * Description: reads in the file of ints, then sorts them into a list
     * Pre-Condition: Reads a file as input
     * Post-Condition: creates a sorted linked list from the values that were input
     */
    bool sortInput();

    /*
     * logError(string)
     * Description:takes a string and writes it to a log file
     * Pre-Condition: takes a string as input
     * Post-Condition: input string is written to log.txt
     */
    void logError(string);

    /*
     * printList(char)
     * Description: prints out all the values of the list in either ascending or descending order
     * Pre-Condition: takes a char as input to decide ascending or descending order
     * Post-Condition: prints the values of the linked list
     */
    bool printList(char);

    /*
     * printEvenList(char)
     * Description: Prints all the even values in the linked list in either ascending or descending order
     * Pre-Condition: takes a char as input to decide ascending or descending order
     * Post-Condition: prints all even values in the linked list
     */
    bool printEvenList(char);

    /*
     * addInt(int)
     * Description: adds an int to the linked list in its sorted place
     * Pre-Condition: takes an int as input
     * Post-Condition: adds the int value to the list
     */
    bool addInt(int);

    /*
     * deleteInt(int)
     * Description: deletes the input int from the list
     * Pre-Condition: takes an int as input
     * Post-Condition: deletes the int from the list
     */
    bool deleteInt(int);

    struct sortedIntVals {
        int value;
        bool even;
        sortedIntVals* next;
        sortedIntVals* previous;
        sortedIntVals* nextEven;
        sortedIntVals* previousEven;
    }*list = new sortedIntVals, *listHead = list, *listTail, *tempPrev,
            *tempEvenPrev, *returnTo, *current, *returnToTemp;

    int listSize = 0, evenListSize = 0;

    int main() {
        char a = 'A';
        char d = 'D';
        sortInput();
        cout << "sorted" << endl;
        addInt(48);
        printList(a);
        printEvenList(a);
        printEvenList(d);
    }

    bool sortInput() {
        ifstream inFile;
        int sinceEven = 0, testInt, selectInt;

        //Tests for the existence of the file
        inFile.open("integer.txt");
        if (inFile.good() != true) {
            logError("Failed to open the file");
            return false;
        }

        //Tests for data in the file
        inFile >> testInt;
        if (testInt == inFile.eof()) {
            logError("No data in file");
            return false;
        }

        //finds the number ints in the file
        while (inFile >> testInt != '\0') {
            listSize++;
        }
        listSize++;

        int rawInt[listSize];

        //resets the file
        inFile.close();
        inFile.open("integer.txt");

        //places values from the file into an array
        for (int i = 0; i < listSize; i++) {
            inFile >> testInt;
            if (testInt < 0) {
                logError("Input value was less than 0, not added to the list");
                i--;
                listSize--;
            } else if (inFile.fail()) {
                logError("Element in file was not an int, Terminating input");
                return false;
            } else {
                rawInt[i] = testInt;

                //finds number of even ints
                if (testInt % 2 == 0) {
                    evenListSize++;
                }
            }
        }
        selectInt = rawInt[0];

        //Sorts the array using a bubble sort
        for (int j = 1; j < listSize + 1; j++) {
            if (rawInt[j - 1] > rawInt[j]) {
                selectInt = rawInt[j];
                rawInt[j] = rawInt[j - 1];
                rawInt[j - 1] = selectInt;
                j = 1;
            }
        }

        //Starts creating the list
        for (int i = 0; i < listSize; i++) {
            list->even = false;
            current = list;
            if (i == 0) {
                list->previous = NULL;
                list->previousEven = NULL;
            }

            list->next = new sortedIntVals;
            list->value = rawInt[i];
            (list->next)->previous = list;

            if (list->value % 2 == 0) {
                list->even = true;
                returnTo = list;
                if (i != 0 && sinceEven > 0) {
                    returnTo = list;
                    for (int i = 0; i < sinceEven; i++) {
                        list = list->previous;
                        list->nextEven = returnTo;
                    }
                    list->nextEven = returnTo;
                    returnTo->previousEven = list;
                    list = returnTo;
                }
                sinceEven = 0;
            }
            if (i == listSize - 1) {
                listTail = list;
                list->next = NULL;
                list->nextEven = NULL;
            }
            list = list->next;
            sinceEven++;
        }
        list = listHead;
        return true;
    }

    bool addInt(int value) {
        if (value < 0) {
            logError("Input value is less than 0");
            return false;
        }
        bool placed = false;
        while (placed == false) {
            if (list->value > value && list->previous == NULL) {
                list->previous = new sortedIntVals;
                returnTo = list;
                list = list->previous;
                list->previous = NULL;
                list->previousEven = NULL;
                if (value % 2 == 0) {
                    returnTo->previousEven = list;
                    list->even = true;
                    evenListSize++;
                }
                list->next = returnTo;
                if (returnTo->even == true) {
                    list->nextEven = returnTo;
                } else {
                    list->nextEven = returnTo->nextEven;
                }
                list->value = value;
                if (value % 2 == 0) {
                    returnTo = list;
                    while (list->even != true && list->next != NULL) {
                        list = list->next;
                        list->previousEven = returnTo;
                    }
                    list->previousEven = returnTo;
                    list = returnTo;
                }
                listHead = list;
                placed = true;
            } else if (list->value > value) {
                returnTo = list;
                tempPrev = list->previous;
                tempEvenPrev = list->previousEven;//I Belive the problem to be here
                list->previous = new sortedIntVals;
                list = list->previous;
                list->previous = tempPrev;
                list->previousEven = tempEvenPrev;
                cout << list->previousEven->value;
                list->previous->next = list;
                list->next = returnTo;
                list->value = value;
                if (value % 2 == 0) {
                    returnTo->previousEven = list;
                    list->even = true;
                    //sets nextEvens
                    returnToTemp = list;
                    list = list->previous;
                    while (list->even != true) {
                        list = list->previous;
                        list->nextEven = returnToTemp;
                    }
                    list = returnToTemp;

                    list->previous->nextEven = list;
                    returnTo->previousEven = list;

                    evenListSize++;
                }
                list->nextEven = returnTo;
                if (returnTo->even == false) {
                    list->nextEven = returnTo->nextEven;
                    if (list->even == true) {
                        returnTo->nextEven->previousEven = list;
                    }
                }
                if (list->next == NULL) {
                    listTail = list;
                }
                placed = true;
            }
            if (returnTo->value == value) {
                cout << "The value was already in the list" << endl;
            }
            list = list->next;
        }
        listSize++;
        list = listHead;
        return true;
    }

    bool deleteInt(int value) {
        if (value < 0) {
            logError("Input value was less than 0");
            return false;
        }
        bool deleted = false;
        while (deleted == false) {
            if (list->value == value) {
                if (list->even == true) {
                    list->previous->nextEven = list->nextEven;
                    list->next->previousEven = list->previousEven;
                }
                (list->previous)->next = list->next;
                (list->next)->previous = list->previous;
                deleted = true;
                delete list;
                listSize--;
            } else if (list->next == NULL) {
                logError("Value to delete was not found in list");
                list = listHead;
                return false;
            }
            list = list->next;
        }
        list = listHead;
        return true;
    }

    bool printList(char direct) {
        if (direct != 'A' && direct != 'D') {
            logError("Invalid Direction selected");
            return false;
        }
        if (direct == 'A') {
            cout << "Values in Ascending order: ";
            for (int i = 0; i < listSize; i++) {
                cout << list->value << " ";
                list = list->next;
            }
            cout << endl;
            list = listHead;
        } else if (direct == 'D') {
            list = listTail;
            cout << "values in descending order: ";
            for (int i = 0; i < listSize; i++) {
                cout << list->value << " ";
                list = list->previous;
            }
            list = listHead;
            cout << endl;
        }
        return true;
    }

    bool printEvenList(char direct) {
        if (direct != 'A' && direct != 'D') {
            logError("Invalid direction input");
            return false;
        }
        if (direct == 'A') {
            if (list->even != true) {
                list = list->nextEven;
            }
            cout << "Even Values in ascending order: ";
            for (int i = 0; i < evenListSize; i++) {
                //list -> nextEven = listHead;
                cout << list->value << " "; //here
                list = list->nextEven;
            }
            cout << endl;
            list = listHead;
        } else if (direct == 'D') {
            list = listTail;
            if (list->even == false) {
                list = list->previousEven;
            }
            cout << "Even Values in descending order: ";
            for (int i = 0; i < evenListSize; i++) {
                if (list->previousEven == NULL) {
                    cout << "Shit, it wasnt set at " << i << endl;
                    return false;
                }
                cout << list->value << " ";
                list = list->previousEven;
            }
            cout << endl;
            list = listHead;
        }
        return true;
    }

    void logError(string error) {
        cout << "ACTION FAILED: See info in log.txt" << endl;
        ofstream logOut;
        logOut.open("log.txt", fstream::app);
        logOut << error << endl;
        logOut.close();
    }

Aucun commentaire:

Enregistrer un commentaire