简体   繁体   English

程序意外退出

[英]Program exits unexpectedly

I am trying to make a program that takes all the data from a file and then the user can decide to add more courses to the file, delete a specific course, or search for a specific course in the file.我正在尝试制作一个从文件中获取所有数据的程序,然后用户可以决定向文件中添加更多课程、删除特定课程或在文件中搜索特定课程。 I am sure that there are more problems then what I am asking for.我敢肯定,比我所要求的问题还要多。

In the createNode function the user is supposed to input all the information about the course, but after the user enters the name of the course the program closes.在 createNode function 中,用户应该输入有关课程的所有信息,但在用户输入课程名称后程序关闭。 I am relatively new to coding, and I have tried looking up solutions to this problem but could not find anything.我对编码比较陌生,我尝试过寻找这个问题的解决方案,但找不到任何东西。

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

enum week {Mon,Tue,Wed,Thu,Fri};

struct courseInfo
{
    string courseName, CourseID, times[5], building, roomNum;
    week day[5];
}course;

struct NodeType
{
    courseInfo *data;
    NodeType *next;
};

//Function that displays all the courses that are in the file including the courses that are added by the user
//Pre:  User inputs the correct file name for the file that has their course information
//Post: Outputs all of the classes in the file for the user to see
void displayAllCourses(string fileName);

//Function that takes a user input course ID and displays that course info
//Pre:  The user inputs a valid course ID
//Post: The class the user searched for is displayed
void searchCourse(string fileName);

//Function that allows the user to add another class to the file
//Pre:  user adds the information in the way they are prompted
//Post:
void addCourse(string fileName);

// Create and return a new node.
// Pre: None
// Post: Returns a pointer to NodeType with all of the data filled in by user
NodeType *CreateNode();

// Add a given node to a list in a sorted position.
// Pre: listPtr set to a valid list, or nullptr
//      newNodePtr assigned to a valid node with valid component value
// Post: listPtr is updated with nodePtr included in the sorted position
void AddNode(string fileName, NodeType *&listPtr, NodeType *newNodePtr);

int main()
{
    NodeType *headPtr;      // Always points to the first node in the list
    NodeType *lastPtr;      // Always points to the last node in the list
    NodeType *currPtr;      // Working pointer. Points to whatever node it needs to
    NodeType *newNodePtr;   // Points to a newly created node
    string fileName;        //Variable for the name of the file the user would like to open
    cout << "Please enter the name of the file you would like to open: " << endl;//Prompts the user for the name of the file they would like to open
    getline(cin, fileName);        //User inputs the file name they want to open
    char answer;
    while(1)                //Loop That repeats until the user inputs that they want to exit
    {
        //prompt the user for what action they would like to do
        cout<<"Type D to display all your courses"<<endl;
        cout<<"Type S to search for a specific course"<<endl;
        cout<<"Type A to add another course"<<endl;
        cout<<"Type E to exit the program"<<endl;
        cout<<"What would you like to do: ";
        cin >> answer;
        cout<<endl;

        //Compares the users choice to the case and executes the code for that case
        switch(answer)
        {
            case 'D':
            displayAllCourses(fileName);    //Function call to display all the courses in the file
            break;
            case 'S':
            {
                searchCourse(fileName);     //Function call to search for a user defined course by ID
                break;
            }
            case 'A':
                CreateNode();
                //AddNode(fileName, headPtr, newNodePtr);            //Function call to add another course to the file
                break;
            default:
            exit(0);
        }
    }
}

NodeType *CreateNode(){
    NodeType *newNodePtr;   // Pointer for new node
    newNodePtr = new NodeType;
    string day;
    cout << "Please enter the Course name: " << endl;
    cin >> newNodePtr->data->courseName;

    cout << "Please enter Course ID: " << endl;
    cin >> newNodePtr->data->CourseID;

    cout << "Please enter the day of the course: " << endl;
    cin >> day;

    cout << "Please enter the time time of the course: " << endl;
    getline(cin, newNodePtr->data->times[0]);
    cout << "Please enter the building name: " << endl;
    getline(cin, newNodePtr->data->building);
    cout << "Please enter the room number: " << endl;
    getline(cin, newNodePtr->data->roomNum);


    if(day=="Monday")
        newNodePtr->data->day[0] = Mon;

        else if(day=="Tuesday")
            newNodePtr->data->day[0] = Tue;

        else if(day=="Wednesday")
            newNodePtr->data->day[0] = Wed;

        else if(day=="Thursday")
            newNodePtr->data->day[0] = Thu;

        else if(day=="Friday")
            newNodePtr->data->day[0] = Fri;

    newNodePtr->next = nullptr;

    return newNodePtr;
}

void AddNode(string fileName, NodeType *&listPtr, NodeType *newNodePtr){
    NodeType *currPtr = listPtr;    // Points to current node in list
    NodeType *prevPtr = nullptr;    // Points to node before the currPtr

    // 1 - Find position in list to add newNodePtr
    // Loop while not at end of list and new node value is greater than currPtr value to find sorted location
    while ((currPtr != nullptr) &&
           (newNodePtr->data->courseName.at(0) > currPtr->data->courseName.at(0))){
//        cout << currPtr->component << " ";        // Echo node be traversed for debugging purposes
        prevPtr = currPtr;
        currPtr = currPtr->next;
    }
    cout << endl;


    // 2 - Insert node
    if ((prevPtr == nullptr) && (currPtr == nullptr)){  // Pointers never moved, so first/only node
        listPtr = newNodePtr;                           // Set listPtr to new (only) node
    }

    else if (prevPtr == nullptr){                       // prevPtr never moved, so need to add to beginning of list
        newNodePtr->next = listPtr;                     // Point newNodePtr->next to current beginning of list
        listPtr = newNodePtr;                           // Make newNodePtr new first node in list
    }

    else if (currPtr == nullptr){
        prevPtr->next = newNodePtr;                     // prevPtr already pointing at last node, so add newPointer as new last node
    }

    else {
        newNodePtr->next = currPtr;                     // Point newNodePtr->next to currPtr
        prevPtr->next = newNodePtr;                     // Update prevPtr->next to insert newNodePTr in list
    }
    fstream file;
    file.open(fileName += ".txt", fstream::app);    //Adds the new course the the course list in the file
    if(!file)
    {
        cout<<"Unable to open file!";
        exit(1);
    }

    cout<<newNodePtr<<endl;
    file<<newNodePtr;
    file.close();
}

void displayAllCourses(string fileName)
{
    ifstream file;
    file.open(fileName += ".txt");              //Opens the user specified file
    if(!file)
    {
        cout<<"Unable to open file!";           //Tells the user that the file could not open
        exit(1);
    }

    int counter=1;
    string fileInfo;                            //String to hold the file information
    while(getline(file, fileInfo))              //Loop to display everything in the file
    {
        cout<<counter<<": "<<fileInfo<<endl;
        counter++;
    }
    cout<<endl;
    file.close();
}

void searchCourse(string fileName)
{
    string courseName;                          //Variable to hold the ID that the user wants to search for

    cout<<"Enter the course name: " << endl;            //Prompt the user for the ID of the course
    cin>>courseName;                            //User inputs the ID for the course

    ifstream file;
    file.open(fileName += ".txt");              //Open user specified file
    if(!file)
    {
        cout<<"Unable to open file!";
        exit(1);
    }

    string line;

    while( getline(file, line ))
    {
        size_t pos = line.find(courseName);
        if ( pos != string::npos)
            cout << line << endl;
    }
    cout<<endl;
    file.close();
}

In CreateNode() , when you call new NodeType you are creating a new NodeType object, but NodeType has no constructor implemented, so its data and next members are left uninitialized .CreateNode()中,当您调用new NodeType时,您正在创建一个新的NodeType object,但NodeType没有实现构造函数,因此它的datanext成员未初始化 You are later assigning nullptr to newNodePtr->next , but you never assign newNodePtr->data to point anywhere.您稍后将nullptr分配给newNodePtr->next ,但您从未分配newNodePtr->data指向任何地方。 Thus, when you try to read the user's input into newNodePtr->data->courseName , newNodePtr->data is not pointing at a valid courseInfo object, so you encounter undefined behavior that is crashing your process.因此,当您尝试将用户的输入读入newNodePtr->data->courseName时, newNodePtr->data未指向有效的courseInfo object,因此您会遇到导致进程崩溃的未定义行为

You need to construct a courseInfo object for newNodePtr->data to point at, eg:您需要为newNodePtr->data构建一个courseInfo object 指向,例如:

NodeType *newNodePtr;
newNodePtr = new NodeType;
newNodePtr->data = new courseInfo; // <-- add this!

However, you should move that initialization into NodeType 's constructor instead, eg:但是,您应该将该初始化移动到NodeType的构造函数中,例如:

struct NodeType
{
    courseInfo *data;
    NodeType *next;

    NodeType() : data(new courseInfo), next(nullptr) {}
};

A better option would be to change the data member to be an actual courseInfo object instead of a courseInfo* pointer, eg:更好的选择是将data成员更改为实际courseInfo object 而不是courseInfo*指针,例如:

struct NodeType
{
    courseInfo data;
    NodeType *next = nullptr;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM