您的位置:首页 > 编程语言 > C语言/C++

C++ 将数据写入链表,将链表写入文件,再将文件中的内容读出

2017-08-26 19:14 447 查看
就算世界荒芜,总有一个人,他会是你的信徒。          ----《独木舟里的星星》
第一步:创建一个节点
template<typename
T>
class
Node
{
public:
    Node(T data)
    {
        m_data
= data;
        m_pNext
= NULL;
    }

    const
T &getData()
    {
        return
m_data;
    }

    Node<T>
* &getNext()
    {
        return
m_pNext;
    }
private:
    T m_data;
    Node *m_pNext;
};
     这里用到了类模板,因为这里的数据部分类型无法确定。

第二步:创建链表
template<typename
T>
class
List
{
public:
    List()
    {
        m_iLen
= 0;
        m_pFirstNode
= NULL;
    }

    Node<T>*
getFirstNode()
    {
        return
m_pFirstNode;
    }

    int
getListLen()
    {
        return
m_iLen;
    }

    void
insert(T data)
    {
        Node<T>
*node
= new
Node<T>(data);
        node->getNext()
= m_pFirstNode;
        m_pFirstNode
= node;
        m_iLen++;
    }

    void
display()
    {
        Node<T>
*tmp
= m_pFirstNode;
        for(int
i =
0; i <
m_iLen; i++)
        {
            cout
<< tmp->getData()
<< endl;
            tmp
= tmp->getNext();
        }
    }

private:
    int
m_iLen;
    Node<T>
*m_pFirstNode;
};
       一般习惯将链表头定义的与其他节点不同,链表头可以放很多信息,例如:链表长度、作者、修改人、创建日期等等,当后面节点加入的时候不会每个节点都有这些信息。

。。。可以在主函数中试一下链表。。。
int main(void)
{
    List<int> intList;
    intList.insert(2);
    intList.insert(1);
    intList.insert(5);
    intList.insert(3);
    intList.insert(4);
    cout << "打印链表" << endl;
    intList.display();

第四步:链表写好后,我们将链表写入文件中
        fstream file1;
        file1.open("int.txt");
        file1 << intList;
        将文件以读写的方式打开,记得要提前创建文件int.txt,因为以读写方式打开文件的时候,如果文件不存在,程序不会自动创建。同样,以只读打开也是一样,只有以只写打开的时候才会自动创建。如果仅仅这样写,编译的时候肯定无法通过,因为无法将一个链表类型的数据直接写入文件。我们需要将<<运算符重载。
重载运算符: <<
template<typename T>
fstream &operator << (fstream &file, List<T> &list)
{
    Node<T> *tmp = list.getFirstNode();
    int len = list.getListLen();
    for(int i = 0; i < len; i++)
    {
        file << tmp->getData();
        tmp = tmp->getNext();
    }
    return file;
}
写完后,再执行file1.intList; 就不会报错了。

第五步:从文件中读取数据到链表
    file1.seekg(0, ios_base::beg);
    cout << "--------读取文件里的链表------------" << endl;
    List<int> intList2;
<
1320b
span style="font-size:10pt;">    int data = 0;
    while(1)
    {
        file1 >> data;
        intList2.insert(data);
        if(file1.eof())
        {
            break;
        }
    }
    intList2.display();
    file1.close();
思路很简单,首先将文件的读写位置设置到首部,因为我们在写入文件的时候,读写位置到了最后,这时候直接读是读不到数据的。然后将文件里的内容读到临时变量data中,然后插入的时候调用有参构造函数,输入参数data,生成新链表。读取完退出,最后打印显示。

上面的链表只针对一般的数据类型有效,如果我们的数据部分是自己构造的类呢?
第一步:创建一个类(以student为例)
class
Student
{
public:
    Student(int
id =
1000, string name
= " ",
float
score =
0.0f)
    {
        m_iId
= id;
        m_strName
= name;
        m_fScore
= score;
    }

    friend
ostream &operator
<< (ostream
&out,
const Student
&stu);

private:
    int
m_iId;
    string m_strName;
    float
m_fScore;
};

第二步:重载运算符 <<
ostream &operator
<< (ostream
&out,
const Student
&stu)
{
    out <<" "
<< stu.m_iId
<<
" " << stu.m_strName
<<
" " << stu.m_fScore
;
}
这里重载是因为1、打印的时候无法直接直接输入一个Student类型,即:cout << stu 是无法直接实现的, 2、写入文件的时候同样无法直接写入一个Student类型。但为什么只重载ostream中的<<就可以同时实现两个呢?因为fstream继承了iostream,而iostream又继承了istream和ostream。关系如下图:



这之后的操作大同小异,大家可以自行理解。
下面是全代码,以及打印结果:

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

class
Student
{
public:
    Student(int
id =
1000, string name
= " ",
float
score =
0.0f)
    {
        m_iId
= id;
        m_strName
= name;
        m_fScore
= score;
    }

    friend
ostream &operator
<< (ostream
&out,
const Student
&stu);
    //friend fstream &operator << (fstream &file, const Student &stu);
private:
    int
m_iId;
    string m_strName;
    float
m_fScore;
};

ostream &operator
<< (ostream
&out,
const Student
&stu)
{
    out <<" "
<< stu.m_iId
<<
" " << stu.m_strName
<<
" " << stu.m_fScore
;
}

template<typename
T>
class
Node
{
public:
    Node(T data)
    {
        m_data
= data;
        m_pNext
= NULL;
    }

    const
T &getData()
    {
        return
m_data;
    }

    Node<T>
* &getNext()
    {
        return
m_pNext;
    }
private:
    T m_data;
    Node *m_pNext;
};

template<typename
T>
class
List
{
public:
    List()
    {
        m_iLen
= 0;
        m_pFirstNode
= NULL;
    }

    Node<T>*
getFirstNode()
    {
        return
m_pFirstNode;
    }

    int
getListLen()
    {
        return
m_iLen;
    }

    void
insert(T data)
    {
        Node<T>
*node
= new
Node<T>(data);
        node->getNext()
= m_pFirstNode;
        m_pFirstNode
= node;
        m_iLen++;
    }

    void
display()
    {
        Node<T>
*tmp
= m_pFirstNode;
        for(int
i =
0; i <
m_iLen; i++)
        {
            cout
<< tmp->getData()
<< endl;
            tmp
= tmp->getNext();
        }
    }
    
private:
    int
m_iLen;
    Node<T>
*m_pFirstNode;
};

template<typename
T>
fstream &operator
<< (fstream
&file, List<T>
&list)
{
    Node<T>
*tmp
= list.getFirstNode();
    int
len =
list.getListLen();
    for(int
i =
0; i <
len; i++)
    {
        file
<< tmp->getData();
        tmp
= tmp->getNext();
    }
    return
file;
}

int
main(void)
{
    List<int>
intList;
    intList.insert(2);
    intList.insert(1);
    intList.insert(5);
    intList.insert(3);
    intList.insert(4);
    cout <<
"打印链表"
<< endl;
    intList.display();

    fstream file1;
    file1.open("int.txt");
    file1 <<
intList;
    file1.seekg(0, ios_base::beg);
    cout <<
"--------读取文件里的链表------------"
<< endl;
    List<int>
intList2;
    int
data =
0;
    while(1)
    {
        file1
>> data;
        intList2.insert(data);
        if(file1.eof())
        {
            break;
        }
    }
    intList2.display();
    file1.close();

    cout <<
endl <<
endl;
    List<Student>
stuList;
    stuList.insert(Student(1001,
"aa",
23));
    stuList.insert(Student(1002,
"bb",
14));
    stuList.insert(Student(1003,
"cc",
53));
    stuList.insert(Student(1004,
"dd",
25));
    stuList.insert(Student(1005,
"ee",
94));
    cout <<
"打印链表"
<< endl;
    stuList.display();

    fstream file2;
    file2.open("student.txt");
    file2 <<
stuList;
    file2.seekg(0, ios_base::beg);
    cout <<
"-------读取文件里的链表------------"
<< endl;
    List<Student>
stuList2;
    int
id =
0;
    string name
= " ";
    float
score =
0.0f;
    while(1)
    {
        name.clear();
        file2
>> id >>
name >>
score;
        stuList2.insert(Student(id,
name, score));
        if(file2.eof())
        {
            break;
        }
    }
    stuList2.display();
    file2.close();

    return
0;
}



QQ:1786610699      倔强的木木      2017年8月26日
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息