[英]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
没有实现构造函数,因此它的data
和next
成员未初始化。 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.