以行爲單位的文件處理程序

有些應用中,不一定必須要數據庫支持,紀錄可以保存在文本里,此時,
如何對這些記錄進行增刪改查的操作呢?這裏以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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章