write/read vector with fstream

在开发一个简单图书管理系统时,想用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();

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

时间: 2024-10-27 19:24:04

write/read vector with fstream的相关文章

编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个对立的元素存于vector中

#include<iostream> #include<string> #include<vector> #include<fstream> using namespace std; int main(int argc,char *argv[]) { ifstream input(argv[1]); vector<string> vec; string tmp; while(getline(input,tmp)) { vec.push_back(

文本查询程序

我们实现一个简单的文本查询程序.我们的程序允许用户在一个给定文件中查询单词,查询结果是单词在文件中出现的次数及所在行的列表.如果一个单词在一行中出现多次,此行只列出一次. #include<iostream> #include<map> #include<set> #include<string> #include<vector> #include<fstream> #include<sstream> #include&l

C/C++读写csv文件(用getline探测逗号分隔符)

csv文件其实就是文本文件,每行字段用逗号分隔. 代码 [cpp] view plain copy print? #include <iostream> #include <string> #include <vector> #include <fstream> #include <sstream> using namespace std; int main() { // 写文件 ofstream outFile; outFile.open(&q

Rock-Paper-Scissors Tournament[HDU1148]

Rock-Paper-Scissors TournamentTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2178 Accepted Submission(s): 693 Problem DescriptionRock-Paper-Scissors is game for two players, A and B, who each choo

最大子列和问题

转自:http://www.cnblogs.com/CCBB/archive/2009/04/25/1443455.html 问题描述: 输入一组整数,求出这组数字子序列和中最大值.也就是只要求出最大子序列的和,不必求出最大的那个序列.例如: 序列:-2 11 -4 13 -5 -2,则最大子序列和为20. 序列:-6 2 4 -7 5 3 2 -1 6 -9 10 -2,则最大子序列和为16. 算法一: //穷举法,复杂度O(n^3) long maxSubSum1(const vector<

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记9——游戏摄像机&amp;三维地形的构建

第21章 游戏摄像机的构建 之前的程序示例,都是通过封装的DirectInput类来处理键盘和鼠标的输入,对应地改变我们人物模型的世界矩阵来达到移动物体,改变观察点的效果.其实我们的观察方向乃至观察点都是没有变的,变的只是我们3D人物的位置.说白了就是用D3DXMatrixLookAtLH在资源初始化时固定住视角,在程序运行过程中接收到消息并改变三维人物模型的世界矩阵而已.这章的主要内容就是创建出一个可以在三维空间中自由移动的摄像机类,我们准备给这个摄像机类取名为CameraClass. 设计摄

7-将sift特征保存到文档里

1- http://blog.csdn.net/woainiwss/article/details/49660393 2- #include <opencv2/opencv.hpp> #include <opencv2/features2d/features2d.hpp> #include<opencv2/nonfree/nonfree.hpp> #include<opencv2/legacy/legacy.hpp> #include<vector&g

c++文件流的基本操作

C++编程语言在实际编程中,对于文件的操作是一个比较简单的操作,大家可以通过一些简单的实例就能充分的掌握这一应用技巧,并在实际编程中给自己的程序开发带来一些帮助.下面就让我们一起来看看C++文件流操作的相关应用技巧吧. C++文件流操作之文件写入: #include < fstream> #include < iostream> using namespace std; int main(){ string str; ofstream out("d.txt");

[Project] MiniSearch文本检索简介

1. 预处理过程 预处理主要用来事先生成程序在运行过程中可能用到的数据,以便加速处理时间. 预处理的过程主要生成程序所需的三个文件:网页库文件,网页位置信息文件和倒排索引文件. 网页库文件 其中网页库文件ripepage.lib主要是以格式化的数据存储大量的网页信息,每个网页的格式化数据为: <doc> <docid>id</docid> <docurl>url</docurl> <doctitle>title</doctitl