有些應用中,不一定必須要數據庫支持,紀錄可以保存在文本里,此時,
如何對這些記錄進行增刪改查的操作呢?這裏以C++標準庫提供了一個類,
來處理此類問題。該類以行爲單位進行操作,設一條紀錄存爲一行。只要
拿到一行數據,再用string類進行其他處理也就不費事了。
頭文件:
/*************************************************************
* LineFile class Interface
*
* [author] iori.ogami
* [date] 2005-1-15
* [ver] 1.3
* [env] Visual C++ 6.0 sp5
*
**************************************************************/
#pragma warning(disable:4786)
#include <string>
#include <vector>
#include <fstream>
class LineFile
{
public:
LineFile(){};
LineFile(std::string fileName);
LineFile(const LineFile& lf);
LineFile& operator =(const LineFile& lf);
virtual ~LineFile();
long GetLineCount() const { return ln_cnt; }
std::string GetLineText(long lnnum) const;
void UpdateLine(long lnnum, std::string txt);
void InsertLine(long lnnum, std::string txt);
void DeleteLine(long lnnum);
void AddLine(std::string txt);
long GetLineByKeyWord(std::string keyWord) const;
std::vector<long> GetLinesByKeyWord(std::string keyWord) const;
protected:
std::fstream* pFile;
std::vector<std::string> vec;
std::string file_name;
long ln_cnt;
private:
bool Reset();
void dump();
};
CPP文件:
/************************************
implementation of LineFile class
*************************************/
#include "LineFile.h"
#include <iostream>
#include <ios>
#define MAX_CHAR 1024 // max chars in a line, define your own MAX_CHAR here
using namespace std;
/*
* constructor
*/
LineFile::LineFile(std::string fileName): file_name(fileName),ln_cnt(0)
{
pFile = new fstream( file_name.c_str(), ios_base::out|ios_base::app ); // create if not found
pFile->close();
pFile->open(file_name.c_str(), ios_base::in | ios_base::out); // reopen for read and write
char s[MAX_CHAR] = {0};
string ss;
while( pFile->getline(s,MAX_CHAR) )
{
cout<<s<<endl;
ss = s;
vec.push_back(ss);
}
ln_cnt = vec.size();
pFile->clear();
pFile->seekg( ios_base::beg );
cout<<"construct end. line number: "<<ln_cnt<<endl;
}
/*
* copy constructor
*/
LineFile::LineFile(const LineFile& lf):
file_name(lf.file_name),
vec(lf.vec),
ln_cnt(lf.ln_cnt)
{
pFile = new fstream( lf.file_name.c_str(), ios_base::in | ios_base::out );
}
/*
* the destructor
*/
LineFile::~LineFile()
{
if(pFile)
{
if(pFile->is_open()) pFile->close();
delete pFile;
}
}
/*
* move the stream poiter to the start position. if the stream status is 'fail', recover it.
*/
bool LineFile::Reset()
{
if( pFile->bad() )
{
cout<<"[LineFile::Reset] bad stream"<<endl;
return false;
}
if( pFile->fail() ) pFile->clear();
pFile->seekg( ios_base::beg );
return true;
}
/*
* save the file text from vector to the file stream.
*/
void LineFile::dump()
{
// reopen and trunk the file
Reset();
pFile->close();
pFile->open(file_name.c_str(), ios_base::out | ios_base::trunc);
ln_cnt = vec.size();
for(long i=0; i<ln_cnt; i++)
{
string s = vec[i];
*pFile<<s.c_str()<<endl;
}
pFile->close();
pFile->open( file_name.c_str(), ios_base::in | ios_base::out );
}
/*
* evaluate operator '='
*/
LineFile& LineFile::operator =(const LineFile& lf)
{
file_name = lf.file_name;
ln_cnt = lf.ln_cnt;
if( !vec.empty() ) vec.clear();
vec = lf.vec;
if(pFile)
{
if(pFile->is_open()) pFile->close();
delete pFile;
}
pFile = new fstream( lf.file_name.c_str(), ios_base::in | ios_base::out );
return *this;
}
/******************************/
// the interfaces
/******************************/
/*
* get a string by line number,note that the feedline character '/n' is not included.
*/
string LineFile::GetLineText(long lnnum) const
{
if( lnnum >ln_cnt || lnnum<=0 )
{
cout<<"[LineFile::GetLineText] illegal line number: "<<lnnum<<endl;
return "";
}
return vec[lnnum-1];
}
/*
* insert a line at lnnum, and append a feedline character.
*/
void LineFile::InsertLine(long lnnum, std::string txt)
{
if( lnnum >ln_cnt || lnnum<=0 )
{
cout<<"[LineFile::InsertLine] illegal line number: "<<lnnum<<endl;
return;
}
vector<string>::iterator iter = vec.begin();
for(long i=0; i<lnnum-1; i++,iter++);
vec.insert(iter, txt);
dump();
}
/*
* update the specifized line with a new string, also append a feedline character.
*/
void LineFile::UpdateLine(long lnnum, std::string txt)
{
if( lnnum >ln_cnt || lnnum<=0 )
{
cout<<"[LineFile::UpdateLine] illegal line number: "<<lnnum<<endl;
return;
}
vec[lnnum-1] = txt;
dump();
}
/*
* delete a line
*/
void LineFile::DeleteLine(long lnnum)
{
if( lnnum >ln_cnt || lnnum<=0 )
{
cout<<"[LineFile::DeleteLine] illegal line number: "<<lnnum<<endl;
return;
}
vector<string>::iterator iter = vec.begin();
for(int i=0; i<lnnum-1; i++,iter++);
vec.erase(iter);
dump();
}
/*
* append a line at the end of the file.
*/
void LineFile::AddLine(std::string txt)
{
vec.push_back(txt);
dump();
}
/*
* get the line number by a key word, return 0 if not found.
*/
long LineFile::GetLineByKeyWord(string keyWord) const
{
for(long i=0; i<ln_cnt; i++)
{
if( vec.at(i).find(keyWord)!=-1 )
return i+1;
}
return 0;
}
/*
* get the line numbers by a key word.
*/
vector<long> LineFile::GetLinesByKeyWord(string keyWord) const
{
vector<long> v;
for(long i=0; i<ln_cnt; i++)
{
if( vec.at(i).find(keyWord)!=-1 )
v.push_back(i+1);
}
return v;
}