我希望我的程序在其链接列表中保留其信息,即使它已经结束。一种方法是从文件中读取并在完成后将析构函数保存到同一文件中。我有代码打印到析构函数中的文件,但是从我的文件中读取并存储它让我疯了。我尝试了很多想法,但我不能让它工作。任何人对添加或修复的内容有任何建议?初学者程序员在这里。 我已经单独添加,删除和清除应用的功能。
我正在读取的文件如下所示:
HAHA
HEHE
MEME
OEL
URNE
WUWJ
我想将每个字符串放入我的链表中。这是我的代码:
#pragma once
#include <string>
using namespace std;
class StringList;
class StringList
{
private:
struct StringListNode
{
StringListNode *pPrev;
string data;
StringListNode *pNext;
};
public:
StringList();
~StringList();
void addToBottom(string s);
void addToTop(string s);
void remove(string s);
void add(string s);
string print();
void clear();
bool isEmpty() {return (pTop==NULL);}
private:
StringListNode * pTop;
StringListNode * pBottom;
StringListNode *find(const string &s);
};
功能:
#include "StringList.h"
#include <string>
#include<iostream>
#include<fstream>
using namespace std;
StringList::StringList()
{
std::ifstream input( "Read.txt" );
pTop = NULL;
pBottom = NULL;
for( std::string line; getline( input, line ); )
{
add(line);
}
}
StringList::~StringList() {
ofstream ofs("Read.txt");
StringListNode *next;
for (StringListNode *sp = pTop; sp != 0; sp = next)
{
ofs << sp->data << endl;
next = sp->pNext;
delete sp;
}
}
void StringList::add(string s) //adds and places in alphabetical order
{
if(pTop)
{
StringListNode *iter = pTop;
while (iter && s > iter->data)
iter = iter->pNext;
if (iter)
{
// insert before
StringListNode *A=new StringListNode;
A->data = s;
A->pNext = iter;
A->pPrev = iter->pPrev;
if (iter->pPrev)
iter->pPrev->pNext = A;
else
pTop = A;
iter->pPrev = A;
return;
}
}
// add to bottom
addToBottom(s);
}
StringList::StringListNode *StringList::find(const string &s) //basic search function
{
StringListNode *sp = pTop; // Search
while (sp != 0 && sp->data != s)
sp = sp->pNext;
return sp;
}
void StringList::addToTop(string s) //add to top of nodes
{
if(isEmpty())
{
StringListNode * pNewNode;
pNewNode = new StringListNode;
(*pNewNode).data = s;
pTop=pNewNode;
pBottom=pNewNode;
(*pNewNode).pPrev = NULL;
(*pNewNode).pNext = NULL;
}
else //it's not empty
{
StringListNode * pNewNode;
pNewNode = new StringListNode;
(*pNewNode).data = s;
(*pNewNode).pNext = pTop;
(*pTop).pPrev = pNewNode;
(*pNewNode).pPrev =NULL;
pTop=pNewNode;
}
}
void StringList::addToBottom(string s) // add to bottom
{
if(isEmpty())
{
StringListNode * pNewNode;
pNewNode = new StringListNode;
(*pNewNode).data = s;
pTop=pNewNode;
pBottom=pNewNode;
(*pNewNode).pPrev = NULL;
(*pNewNode).pNext = NULL;
}
else
{
StringListNode * pNewNode;
pNewNode = new StringListNode;
(*pNewNode).data = s;
(*pBottom).pNext = pNewNode;
(*pNewNode).pPrev = pBottom;
(*pNewNode).pNext =NULL;
pBottom=pNewNode;
}
}
string StringList::print()
{
string result;
StringListNode * pCurrent;
pCurrent=pTop;
while(pCurrent!=NULL)
{
result+=(*pCurrent).data+"\n";
pCurrent=(*pCurrent).pNext;
}
return result;
}
void StringList::clear()
{
pTop = NULL;
pBottom = NULL;
}
void StringList::remove(string s)
{
StringListNode *curr = this->find(s);
if (curr->pPrev != 0)
curr->pPrev->pNext = curr->pNext;
if (curr->pNext != 0)
curr->pNext->pPrev = curr->pPrev;
if (pTop == curr)
pTop = curr->pNext;
if (pBottom == curr)
pBottom = curr->pPrev;
}
答案 0 :(得分:1)
构造函数中有错误,特别是内存泄漏:
for each string s // read from file but how do i write this?
{
cur = new StringListNode(s); // call the constructor of StringListNode
cur = cur->pNext;
}
您创建了一个节点,但是您立即用节点的初始next
指针替换指向该节点的指针。
就从文件中读取值而言,我建议您搜索Stack Overflow中的“[c ++]从文件中读取”。最近有这么多。
编辑1:构造函数更正
while (read data succeeds)
{
add(data); // why not use your own function?
}
为了提高追加效率,您可能希望维护指向最后一个节点的指针。
void append(data)
{
p = new node(data);
last->next = p;
last = p;
}
答案 1 :(得分:0)
我在你的删除功能中注意到你忘了if语句。如果您输入的内容不在列表中,会发生什么?
我相信你需要类似的东西
if (curr == 0)
{
return;
}
还可以尝试输入/输出文件
ifstream in;
in.open("Read.txt");
StringListNode * pCurrent;
pCurrent = new StringListNode;
pCurrent = pTop;
while(pCurrent && (in >> pCurrent->data))
{
pCurrent = pCurrent->pNext;
}
in.close();
StringList::~StringList()
{
ofstream out;
out.open("Read.txt");
StringListNode * pCurrent;
pCurrent = new StringListNode;
pCurrent = pTop;
while(pCurrent != 0)
{
out << pCurrent->data << endl;
pCurrent = pCurrent->pNext;
}
out.close();
}
该输出应该有效。我刚刚证实了这一点。我认为那应该用输入修复崩溃问题。