IM getting an error that the apointment isnt initialized but idk what to do about when i remove the whole appointment part , the code works perfectly . I tried everything but i have no idea what to do since im still a beginner so any help is appreciated ! thanks
#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);
}
Maybe the problem is that appointment isnt initialized right or should be initialized in the main fucntion perhaps but i tried it and im still getting the same error about something being wrong with thr initialization
CodePudding user response:
In your Employee
structure, your Appointment* Calendar;
is set to NULL by default. So in your parsefile()
function, when you do getline(f, efile.Calendar->Title, '\t');
that is an obvious Segmentation Fault because your efile.Calendar
is NULL.
Also, it might be a good idea to use istringstream
to parse your string instead of using getline()
with the delimiter. This is also shown in official documentation here
Modify your parsefile
method like this:
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();
}
This will now ensure that you are allocating the correct memory for every pointer you are using before performing any operation on it. In your InsertAtDoublyTail(Company *c, Employee e)
you don't have to do a hard copy every attribute inside the pointers.
Another problem that I see in your code is that in your head2tail
method, you are using the starting point as Employee* cur = c->head;
but nowhere in your code are you assigning anything to c->head
. This means that c->head
will always be NULL and hence nothing will actually print.
One more issue that I see is that in your InsertAtDoublyTail(Company* c, Employee* e)
, you have this:
tmp->previous = c->tail;
tmp->next = NULL;
c->tail->next = tmp;
c->tail = tmp;
For the first employee that you add to the company, c-tail
will be NULL. So c->tail->next = tmp
will result in a Segmentation Fault. You need to modify your function like this:
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;
}
}
This should fix everything. When I run the entire code, (after adding more rows to the file1.txt) I see this:
1 sara laban [email protected] business 20 5 20 10 3000
2 Rami lawen [email protected] marketing 50 5 50 10 5000
3 Rami lawen [email protected] marketing 50 5 50 10 5000
4 sara laban [email protected] business 20 5 20 10 3000
5 Rami lawen [email protected] marketing 50 5 50 10 5000
6 Rami lawen [email protected] marketing 50 5 50 10 5000
7 sara laban [email protected] business 20 5 20 10 3000
8 Rami lawen [email protected] marketing 50 5 50 10 5000
9 Rami lawen [email protected] marketing 50 5 50 10 5000
10 sara laban [email protected] business 20 5 20 10 3000
11 Rami lawen [email protected] marketing 50 5 50 10 5000