将文本文件读取到双向链表并输出 - C ++

时间:2017-10-25 03:48:16

标签: c++ eclipse pointers linked-list doubly-linked-list

我试图读取文件并使用双向链表来存储数据并输出存储的数据。但每当我运行我的程序时,它都不会输出任何内容并终止。编译代码时没有错误。

带有预处理器指令和结构的头文件

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

typedef struct sentry  sentry;

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 slist
{
    int length;
    sentry *first;
    sentry *last;
};
struct sentry
{
    slist *list;
    sentry *next;
    sentry *prev;
    stud *data;
};

void readFile(slist *&header);

我的main.cpp 它调用读取文件函数并输出

#include "header.h"

int main()
{
    slist *header = NULL;

    sentry *temp, *node;
    temp = header->first;

    readFile(header);

    for(int i=0; i<header->length; ++i)
    {
        cout << node->data->term << endl;
        cout << node->data->title << endl;
        cout << node->data->description << endl;
        cout << node->data->tktNum << endl;
        cout << node->data->location << endl;
        cout << node->data->lecDay << endl;
        cout << node->data->instructor << endl;
        cout << node->data->labLoc << endl;
        cout << node->data->labInstruct << endl;
        cout << node->data->units << endl;
        cout << node->data->preReqs << endl;
        cout << node->data->grade << endl;

        node-> prev = header-> last;
        node-> next = NULL;
        temp = header -> last;
        temp-> next = node;
        header-> last = node;
        node = temp->prev;
    } 

    return 0;
}

我的readFile函数 - 它从文本文件读入并将数据存储到链表

#include "header.h"

void readFile(slist *&header)
{
    ifstream fin;
    sentry *node, *temp;

    fin.open("data.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++;
    }
}

我的data.txt文件(用于从中读取数据的文本文件)

Fall 2222
CS101
Computer Science Intro
12345
SCI546
MWF 1230PM
John Doe
SCI547
MWF 230PM
John Doe
4
N/A
B

Spring 111
English 101
Intro to English
6789
LI123
TTH 130PM
Jane Doe
N/A
N/A
N/A
N/A
3
N/A
A

1 个答案:

答案 0 :(得分:1)

slist *header = NULL;

您永远不会为header分配任何内容。 header始终为NULL。还可以将其称为list,而不是header。你需要:

slist list;

你有其他未初始化的指针,例如sentry *node;你不能使用它,除非它指向某个东西。

你在某些部分使用C风格的声明。 C型结构可以如下:

typedef struct sentry_t sentry; //in C

在C ++中,您只需编写struct sentry;

即可

但你实际上并不需要这个。您需要以下结构:

struct stud
{
    ... as before
};

struct snode
{
    stud data;
    snode *next;
    snode *prev;
};

struct slist
{
    int length;
    snode *head;
    snode *tail;
};

slist是双向链表,snode是其节点。

请注意,我更改了结构,现在stud已包含在snode中,因此您无需使用new进行单独分配(在实际应用中必须释放所有内存,你想避免不必要的分配)

现在您可以声明并初始化您的列表:

int main()
{
    //declare and initialize the list
    slist list;
    list.head = NULL;
    list.tail = NULL;
    list.length = 0;

    readFile(list);

    snode *node = list.head;
    for(int i = 0; i < list.length; i++)
    {
        cout << node->data.term << endl;
        cout << node->data.title << endl;
        cout << node->data.description << endl;
        ...
        node = node->next;
        cout << "\n";
    }

    return 0;
}

读取功能应如下:

void readFile(slist &list)
{
    ifstream fin("file");
    while(fin.good())
    {
        snode *node = new snode;
        if(list.head == NULL)
        {
            node->prev = NULL;
            node->next = NULL;
            list.head = node;
            list.tail = node;
        }
        else
        {
            list.tail->next = node;
            node->prev = list.head;
            node->next = NULL;
            list.tail = node;
        }

        getline(fin, node->data.term);
        getline(fin, node->data.title);
        getline(fin, node->data.description);
        ...
        getline(fin, node->data.grade);
        list.length++;

        string blankline;
        if(!getline(fin, blankline))
            break;
    }
}

使用fin.good()代替!fin.eof()。请注意,文件中有一个空行。你想跳过它,或者当它到达最后一行时打破循环。