我试图从已经从文件读入的数据中删除双向链表中的节点,并将其重写为具有未删除节点的文件。但我做错了。
它只删除节点的一部分,或者它不删除任何东西(起始节点)。
这是我的标题
hw07.h
#ifndef HW07_H_
#define HW07_H_
#include <iostream>
#include <fstream>
using namespace std;
typedef struct slist slist;
struct stud
{
string term;
string title;
string description;
string tktNum;
string location;
string lecDay;
string instructor;
string labLoc;
string labDay;
string labInstruct;
string units;
string preReqs;
string grade;
};
struct sentry
{
slist *list;
sentry *next;
sentry *prev;
stud *data;
};
struct slist
{
int length;
sentry *first;
sentry *last;
};
void readFile(slist *&header);
void deleteDataTN(slist *&header);
#endif
我的主要
hw07.cpp
#include "hw07.h"
int main()
{
slist *header = NULL;
readFile(header);
deleteDataTN(header);
return 0;
}
我的readFile函数
readFile.cpp
#include "hw07.h"
void readFile(slist *&header)
{
ifstream fin;
sentry *node, *temp;
fin.open("sbclassdb.txt");
while(!fin.eof())
{
if(header == NULL)
{
header = new slist;
header-> length = 0;
header-> first = NULL;
header-> last = NULL;
node = new sentry;
header-> first = node;
header-> last = node;
node-> prev = NULL;
node-> next = NULL;
}else
{
node = new sentry;
node-> prev = header-> last;
node-> next = NULL;
temp = header -> last;
temp-> next = node;
header-> last = node;
}
node->data = new stud;
getline(fin, node->data->term);
getline(fin, node->data->title);
getline(fin, node->data->description);
getline(fin, node->data->tktNum);
getline(fin, node->data->location);
getline(fin, node->data->lecDay);
getline(fin, node->data->instructor);
getline(fin, node->data->labLoc);
getline(fin, node->data->labDay);
getline(fin, node->data->labInstruct);
getline(fin, node->data->units);
getline(fin, node->data->preReqs);
getline(fin, node->data->grade);
header->length++;
string blankLine;
if(!getline(fin, blankLine))
break;
}
fin.close();
}
我的deleteData函数
deleteDataTN.cpp
#include "hw07.h"
void deleteDataTN(slist *&header)
{
sentry *node, *temp;
string ticketNum;
ofstream fout;
int index;
bool found;
found = false;
index = 0;
cout << "Ticket Number: ";
getline(cin, ticketNum);
node = header->first;
while(index < header->length && !found)
{
if(node->data->tktNum == ticketNum)
{
found = true;
free(node->data);
}
else
{
++index;
temp = node;
node = temp->next;
}
fout.open("sbclassdb.txt");
node = header->first;
for(int i=0; i<header->length; ++i)
{
fout << node->data->term << endl;
fout << node->data->title << endl;
fout << node->data->description << endl;
fout << node->data->tktNum << endl;
fout << node->data->location << endl;
fout << node->data->lecDay << endl;
fout << node->data->instructor << endl;
fout << node->data->labLoc << endl;
fout << node->data->labDay << endl;
fout << node->data->labInstruct << endl;
fout << node->data->units << endl;
fout << node->data->preReqs << endl;
fout << node->data->grade << endl;
temp = node;
node = temp->next;
fout << "\n";
}
}
我的文本文件用于读取文件
sbclassdb.txt
Fall 2017
CS1A
Intro to Computer Science 1
11111
SM101
TTH 100PM
John Doe
SM102
TTH 300PM
John Doe
5
NA
A
Spring 2018
CS1B
Intro to Computer Science 2
22222
SM101
TTH 200PM
Jane Doe
SM102
TTH 300PM
Jane Doe
5
CS1A
NA
Spring 2018
CS4A
Into to Java for Computer Science
12345
BGS101
MWF 200PM
Bob Smith
BGS102
Bob Smith
4
CS1B
NA
答案 0 :(得分:1)
new
应使用delete
进行清理(free
不是malloc
)
struct sentry{stud *data;...}
可以更改为struct sentry{stud data;...}
。并且不需要sentry::list
成员:
struct sentry
{
sentry *next;
sentry *prev;
stud data;
};
将sentry::data
声明为指针没有任何好处。如果您只是将数据声明为stud data;
,那么您不必使用new
/ delete
分配/免费。 (节点仍然需要new
/ delete
)
void deleteDataTN(slist *&header)
可以声明为void deleteDataTN(slist &header)
,您只需致电deleteDataTN(myheader);
请勿使用while(!fin.eof()){...}
。关于这个问题有很多SO主题。请参阅示例how-does-ifstreams-eof-work。我之前写了一段代码,我认为这是错误的,这是更正后的版本:
while(fin.good())
{
sentry *node = new sentry;
if(header.first == nullptr)
{
node->prev = nullptr;
node->next = nullptr;
header.first = node;
header.last = node;
}
else
{
header.last->next = node;
node->prev = header.last;
node->next = nullptr;
header.last = node;
}
...
}
要删除节点,您可以向slist
添加一个函数:
struct slist
{
...
void remove(sentry *node);
};
void slist::remove(sentry *node)
{
if(!node) return;
if(!first) return;//empty list, do nothing
if(first->next == nullptr)//deleting the only node
{
first = last = nullptr;
}
else if(node == last)//deleting the last node
{
last = node->prev;
node->prev->next = nullptr;
}
else if(node == first)//deleting the first node
{
first = node->next;
first->prev = nullptr;
}
else//deleting a node in the mid
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
length--;
delete node;
}
现在您可以删除任何节点
node = header.first;
while(node)
{
if(node->data.tktNum == "xyz")
{
header.remove(node);
break;
}
node = node->next;
}