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