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

就算世界荒芜,总有一个人,他会是你的信徒。          —-《独木舟里的星星》
第一步:创建一个节点
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;
    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。关系如下图:

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



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

#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
;
}


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

QQ:1786610699      倔强的木木      2017年8月26日

    原文作者:TheTeenager
    原文地址: https://blog.csdn.net/TheTeenager/article/details/77606232
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞