在开发一个简单图书管理系统时,想用vector容器代替链表或数组储存系统运行时的数据。系统关闭时将容器写入本地文件,重新运行系统时将文件数据读入vector容器。

    

     实践期间遇到些许问题。

     成功将vector写入文件,再以流是否到达eof()为终止条件进行读取时。末尾的数据会重复读取。样例如下。

 

 1 #include <iostream>
 2 #include <string>
 3 #include <cstdlib>
 4 #include <vector>
 5 #include <fstream>
 6 
 7 using namespace std;
 8 
 9 class Test{
10    public:
11        Test(){};
12        Test(int _i,string _s):i(_i),str(_s){}
13        void show()
14        {
15            cout << i << " " << str << endl;
16        }
17    private:
18       int i;
19       string str;
20 };
21 
22 int main()
23 {
24     Test t1(1,"try1"),t2(2,"try2"),t3(3,"try3"),t4(4,"try4"),t5(5,"try5");
25     vector<Test> iVec = { t1,t2,t3,t4,t5 };  //c11标准初始化容器
26 
27     ofstream write("test.ini",ios::binary);  //打开文件
28 
29     if( !write ){   //检测是否成功打开
30         cerr << "Can't open the file. Program exit." << endl;
31         exit(1);
32     }
33 
34     write.write(reinterpret_cast<char*>(&iVec[0]),sizeof(Test)*iVec.size());  //开始写入
35 
36     write.close();  //关闭文件
37 
38     Test t;
39     ifstream read("test.ini",ios::binary);
40 
41     if( !read ){
42         cerr << "Can't open the file. Program exit." << endl;
43         exit(1);
44     }
45 
46     while( !read.eof() ){  //出错位置
47         read.read(reinterpret_cast<char*>(&t),sizeof(Test));
48         t.show();
49     }
50 
51     read.close();
52 
53     return 0;
54 }

            会得到错误输出。 1 try1 \n 2 try2 \n 3 try3 \n 4 try4 \n 5 try5 \n 5 try5

      对于这种对输入输出流‘潜规则’理解不透彻的错误,实在无从下手。好在技术论坛上有人遇到相同错误。实在谢天谢地。

      以下剪切自CSDN博客:http://blog.csdn.net/shuilan0066/article/details/4669451

      eof在读取完最后一个数据后,仍是False,当再次试图读一个数据时,由于发现没数据可读了 才知道到末尾了,此时才修改标志,eof变为TRUE。

      也就是说,读完最后一行时,read.eof()还是为false。while继续循环。

      这次循环使read.eof()置为true。且不读取数据到 t ,t 持有上一次循环的数据,从而重复输出了末尾数据。

  

      作出的修改如下。

1     while( read.read(reinterpret_cast<char*>(&t),sizeof(Test)) ){  //判定条件为是否还有数据可读。
2         t.show();
3     }

 

      ---------------------------完美  * * * * * 分割线--------------------------------------------

 

      对Vector一次性读/写。

 1 fstream write("test.bin",ios::out|ios::binary);
 2 
 3     if( !write ){
 4         cout << "Can't open the file.Program exit!" << endl;
 5         exit(1);
 6     }
 7 
 8     write.write(reinterpret_cast<char*>(&sizeOfVec),sizeof(size_t));  //先将容器大小写进文件
 9     write.write(reinterpret_cast<char*>(&iVec[0]),sizeof(Test)*iVec.size());
10 
11     write.close();
12 
13     fstream read("test.bin",ios::in|ios::binary);
14 
15     if( !read ){
16         cout << "Can't open the file.Program exit!" << endl;
17         exit(1);
18     }
19 
20     size_t newSize;
21     vector<Test> newVec;
22     read.read(reinterpret_cast<char*>(&newSize),sizeof(size_t)); //先读取容器大小
23     cout << newSize << endl;
24 
25     newVec.resize(newSize); //将容器清空,且设置大小
26 
27     read.read(reinterpret_cast<char*>(&newVec[0]),sizeof(Test)*newSize);  //一次性将数据读入文件中
28 
29     for( size_t i = 0; i!= newSize; i++ ){
30             newVec[i].show();
31     }  //打印容器
32 
33     read.close();

       望对你有帮助。 后续更新小小图书馆。

 

 

 

 

 

  

 

posted on 2016-07-20 19:40  Elapsed_Time  阅读(572)  评论(0编辑  收藏  举报