有人能帮我理解为什么我在这里出错我相信这是因为约会单链表

Can someone help me understand why im getting an error here I believe its because of the appointment singly linked list

我收到一个错误,指出约会未初始化,但我不知道当我删除整个约会部分时该怎么办,代码运行良好。我尝试了一切,但我不知道该怎么做,因为我仍然是初学者,所以感谢您的帮助!谢谢



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

struct Appointment;
struct Time {
    int Day, Hour, Minute, Second;
};


struct Employee {
    int UniqueID;
    string FirstName,LastName, EmailAddress;
     Appointment* Calendar;
    Employee* next;
    Employee* previous; 
};

struct Company {
    Employee* head, * tail;
};

struct Appointment {
    string Title;
    Time StartingTime;
    int Duration;
    Appointment* next;
};


Company* InitializeDoubly() {
    Company* c = new Company;
    c->head = NULL;
    c->tail = NULL;
    return c;
}

Appointment* Init() {
    return NULL;
}


bool isEmpty(Company *c){
    return(c->head == NULL);
}

void InsertAtDoublyTail(Company* c, Employee e) {
    Employee* tmp = new Employee;
        tmp->UniqueID = e.UniqueID;
        tmp->FirstName = e.FirstName;
        tmp->LastName = e.LastName;
        tmp->EmailAddress = e.EmailAddress;
        tmp->Calendar->StartingTime.Day = e.Calendar->StartingTime.Day;
        tmp->Calendar->StartingTime.Hour = e.Calendar->StartingTime.Hour;
        tmp->Calendar->StartingTime.Minute = e.Calendar->StartingTime.Minute;
        tmp->Calendar->StartingTime.Second = e.Calendar->StartingTime.Second;
        tmp->Calendar->Duration = e.Calendar->Duration;
        tmp->previous = c->tail;
        tmp->next = NULL;
        c->tail->next = tmp;
        c->tail = tmp;
}


void head2tail(Company* c) {
    Employee* cur = c->head;
    
    if (isEmpty(c)) {
        cout << "LIST IS EMPTY";
        return;
    } 
    while (cur != NULL) {
        cout << cur->UniqueID << " " << cur->FirstName << " " << cur->LastName << " " <<
            cur->EmailAddress << " " << cur->Calendar->Title << " " << cur->Calendar->StartingTime.Day << " "
            << cur->Calendar->StartingTime.Hour<<" " << cur->Calendar->StartingTime.Day <<" "<< cur->Calendar->StartingTime.Second
            <<" " << cur->Calendar->Duration<<endl;
        cur = cur->next;
    }
}


void parsefile(Company *c) {
    fstream f("file1.txt", ios::in | ios::out | ios::app);
    Employee efile;
    
    string id,day, hour, minute, second;
    
    while (f) {
        getline(f, efile.FirstName,'\t');
        getline(f, efile.LastName, '\t');
        getline(f, efile.EmailAddress, '\t');
        getline(f, efile.Calendar->Title, '\t');
        getline(f, id, '\t');
        getline(f, day, '\t');
        getline(f, hour, '\t');
        getline(f, minute, '\t');
        getline(f, second, '\t');
        f >> efile.Calendar->Duration; 

        efile.UniqueID = stoi(id);
        efile.Calendar->StartingTime.Day = stoi(day);
        efile.Calendar->StartingTime.Hour = stoi(hour);
        efile.Calendar->StartingTime.Minute = stoi(minute);
        efile.Calendar->StartingTime.Second = stoi(second); 
        InsertAtDoublyTail(c, efile);
        f.ignore(INT_MAX, '\n');
    }
    f.close();
}



int main()
{
    Company* company1 = InitializeDoubly();
    parsefile(company1);
}

也许问题是约会没有正确初始化,或者应该在主函数中初始化,但我试过了,我仍然得到同样的错误,关于初始化有问题

在您的 Employee 结构中,您的 Appointment* Calendar; 默认设置为 NULL。因此,在您的 parsefile() 函数中,当您执行 getline(f, efile.Calendar->Title, '\t'); 时,这是一个明显的分段错误,因为您的 efile.Calendar 为 NULL。

此外,使用 istringstream 来解析字符串可能是个好主意,而不是使用 getline() 和分隔符。官方文档中也有说明here

像这样修改您的 parsefile 方法:

void parsefile(Company *c) {
    fstream f("file1.txt", ios::in);
    Employee efile;
    
    string id,day, hour, minute, second;
    string line; // USED TO READ THE ENTIRE LINE
    while (getline(f, line)) {
        std::istringstream iline(line); // CONVERT IT TO istringstream
        string nextWord = ""; // Used to read every word in the line
        getline(iline, nextWord, '\t');
        efile.FirstName = nextWord; // Set first name
        getline(iline, nextWord, '\t');
        efile.LastName = nextWord; // Set last name
        getline(iline, nextWord, '\t');
        efile.EmailAddress = nextWord;

        // For the Appointment part, create a temporary Appointment variable similar to efile for Employee
        Appointment* temp = new Appointment();
        getline(iline, nextWord, '\t');
        temp->Title = nextWord; // Set the Title

        getline(iline, nextWord, '\t');
        efile.UniqueID = stoi(nextWord);

        Time t; // Create a temporary time object like efile or temp
        getline(iline, nextWord, '\t');
        t.Day = stoi(nextWord);
        getline(iline, nextWord, '\t');
        t.Hour = stoi(nextWord);
        getline(iline, nextWord, '\t');
        t.Minute = stoi(nextWord);
        getline(iline, nextWord, '\t');
        t.Second = stoi(nextWord);

        temp->StartingTime = t; // Set the Time data member of temp to the temporary object you just constructed.

        getline(iline, nextWord, '\t');
        temp->Duration = stoi(nextWord); // Set the duration

        efile.Calendar = temp; // Now set the Calendar data member to the temporary Appointment* object you just created
        InsertAtDoublyTail(c, efile); // Add it to the file
    }
    f.close();
}

现在这将确保您在对每个指针执行任何操作之前为正在使用的每个指针分配正确的内存。在您的 InsertAtDoublyTail(Company *c, Employee e) 中,您不必硬拷贝指针中的每个属性。

我在您的代码中看到的另一个问题是,在您的 head2tail 方法中,您将起点用作 Employee* cur = c->head; 但在您的代码中没有任何地方将任何内容分配给 c->head.这意味着 c->head 将始终为 NULL,因此实际上不会打印任何内容。

我看到的另一个问题是在您的 InsertAtDoublyTail(Company* c, Employee* e) 中,您有这个:

tmp->previous = c->tail;
tmp->next = NULL;
c->tail->next = tmp;
c->tail = tmp;

对于您添加到公司的第一位员工,c-tail 将为 NULL。所以 c->tail->next = tmp 将导致分段错误。您需要像这样修改函数:

void InsertAtDoublyTail(Company* c, Employee e) {
    Employee* tmp = new Employee(); // Create the employee pointer and set all the values.
    tmp->UniqueID = e.UniqueID;
    tmp->FirstName = e.FirstName;
    tmp->LastName = e.LastName;
    tmp->EmailAddress = e.EmailAddress;
    tmp->Calendar = e.Calendar;
    // Add the employee to company
    tmp->previous = c->tail;
    if(c->tail == NULL) { // This means that there is absolutely nothing in the list yet. So assign head and tail to the same tmp that you just created
        c->tail = tmp;
        c->head = tmp; // This needs to be done for your head2tail to work. Without this, your c-> head will be NULL always meaning nothing will print.
    }
    else { // This means that there is at least one Employee in the company. So don't touch the head. Add the new employee to the tail and then just modify the c->tail to point to the last employee that you just added.
        c->tail->next = tmp;
        c->tail = tmp;
    }
}

这应该可以解决所有问题。当我 运行 整个代码时,(在向 file1.txt 添加更多行之后)我看到了这个:

1 sara laban sara@gmail.com business 20 5 20 10 3000             
2 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000              
3 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000
4 sara laban sara@gmail.com business 20 5 20 10 3000
5 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000
6 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000
7 sara laban sara@gmail.com business 20 5 20 10 3000
8 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000
9 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000
10 sara laban sara@gmail.com business 20 5 20 10 3000
11 Rami lawen alwdij@gmail.com marketing 50 5 50 10 5000