C++老代码 -- DBF数据文件操作类DBFile

        十几年前,dBASE、FoxBase和FoxPro数据库盛极一时,C/C++程序员使用C/C++直接操作DBF数据文件是理所当然的事,下面是我在1994年写的一个DBFile类代码。

        DBFIle类的头文件:

//  DBFIO.HPP

#ifndef    __DBFIO_HPP
#define     __DBFIO_HPP

#include 
< stdlib.h >
#include 
< fstream.h >
#include 
" marray.hpp "

const      int

    DB_FieNameSize    
=   11 ;

class  DBField         //  DBF 文件的字段类
{

public :

  
char  name[DB_FieNameSize];
  
char  type;
  
int  off;
  
int  nul;
  unsigned 
char  width;
  unsigned 
char  dec;
  DBField()
  {
    memset( 
this 0 sizeof ( DBField ) );
  }
  
int   operator   ==  (  const  DBField &  );
  
int   operator   <  (  const  DBField &  );
  DBField
&   operator   =  (  const  DBField &  );
  
//  设置字段.参数: 名称, 类型, 宽度, 小数位
   void  SetValue(  char * int int int   =   0  );
};

inline 
int  DBField:: operator   ==  (  const  DBField &  d )
{
  
return   ! strcmp( name, d.name );
}

inline 
int  DBField:: operator   <  (  const  DBField &  d )
{
  
return  strcmp( name, d.name )  <   0   ?   1  :  0 ;
}

inline DBField
&  DBField:: operator   =  (  const  DBField &  d )
{
  memmove( 
this & d,  sizeof ( DBField ) );
  
return   * this ;
}

//  定义排序字段数组类

typedef MSArray 
<  DBField  >     DBFieldArray;

class     DBFile :  public  fstream     //  DBF 文件类
{

  typedef 
struct
  {
    unsigned 
char  dbfflag;
    unsigned 
char  date_n;
    unsigned 
char  date_y;
    unsigned 
char  date_r;
    
long  records;
    unsigned ldb, lrd;
    
char  _nul[ 20 ];
  }DBFSTRUCT;

  DBFSTRUCT str;
  
char   * buf;
  DBField TmpField;
  
int  fields;
  
long  oldrecords;
  
int  openerror;
  DBFieldArray dArray;
  
void  SetBuf();
  
void  Init();
  
void  SetFields(  int  );
  
void  WriteDelFlag(  long int   =   ' * '  );

public :

  DBFile();
  
//  调用 Use( char* )
  DBFile(  const   char *  );
  
//  调用 Use( char*, DBField*, int )
  DBFile(  const   char * , DBField * int  );
  
~ DBFile();
  
//  打开一个已存在文件;参数: 文件名
   void  Use(  const   char *  );
  
//  用一字段数组建立新文件;参数:文件名,字段数组,字段数
   void  Use(  const   char * , DBField * int  );
  
//  关闭文件
   void  Use();
  
void  Close();
  
//  返回记录数
   long  Records();
  
//  返回记录长度
   int  RecSize();
  
//  返回文件头结构长度
   int  TopSize();
  
//  返回字段数
   int  Fields();
  
//  返回打开文件时的错误代码, 错误码:
  
//  0 无错误
  
//  1 文件不存在
  
//  2 建立新文件失败
  
//  3 建立文件时未设置字段
  
//  4 读文件头出错或非 DBF 文件
  
//  5 写文件头出错
  
//  6 内存不够
   int  OpenError();
  
//  把当前记录内容读到缓冲区
   void  Read();
  
//  将缓冲区内容写到当前记录
   void  Write();
  
//  取一字段内容到字符串中;参数:字段名,字符串
   char   * Get(  char * char *  );
  
//  取一字段内容到字符串中;参数:字段序号(按字段名排过序),字符串
   char   * Get( unsigned,  char *  );
  
//  将字符串内容输出到字段中;参数:字段名,字符串
   void  Put(  char * const   char *   );
  
//  将字符串内容输出到字段中;参数:字段序号(按字段名排过序),字符串
   void  Put( unsigned,  const   char *   );
  
//  将一浮点数输出到字段中;参数:,字段名,浮点数
   void  Put(  char * double  );
  
//  将一浮点数输出到字段中;参数:字段序号(按字段名排过序),浮点数
   void  Put( unsigned,  double  );
  
//  将缓冲区内容追加到文件尾;参数:追加标记( 0 空记录 )
   void  Append(  int   =   0  );
  
//  将一字段内容转换为浮点数返回(未检查字段类型);参数: 字段名
   double   operator  [] (  char *  );
  
//  功能同上;参数:字段序号(按字段名排过序)
   double   operator  [] ( unsigned );
  
//  移动文件记录 put 指针;参数: 记录号
   void  Seekp(  long  );
  
//  移动文件记录 get 指针;参数: 记录号
   void  Seekg(  long  );
  
//  将缓冲区内容输出到文件;参数: 记录号
  DBFile &   operator   <<  (  long  );
  
//  从文件中输入内容到缓冲区中;参数: 记录号
  DBFile &   operator   >>  (  long  );
  
//  返回缓冲区指针
   char   * Buf();
  
//  在字段排序数组中查找字段,返回序号,未找到返回 0X7FFF;参数: 字段名
  unsigned FindField(  char *  );
  
//  返回字段排序数组
  DBFieldArray &  FieldArray();
  
//  给记录打上删除标记
   void  Delete(  long  );
  
//  取消记录的删除标记
   void  UnDelete(  long  );
  
//  如记录号在文件记录范围内返回 TRUE, 否则返回 FALSE
   int  InRecords(  long  );

};

inline DBFile::DBFile() : dArray( 
0 1  )
{
  Init();
}

inline 
long  DBFile::Records()
{
  
return  str.records;
}

inline 
int  DBFile::RecSize()
{
  
return  str.lrd;
}

inline 
int  DBFile::TopSize()
{
  
return  str.ldb;
}

inline 
int  DBFile::Fields()
{
  
return  fields;
}

inline 
char   * DBFile::Buf()
{
  
return  buf;
}

inline DBFieldArray
&  DBFile::FieldArray()
{
  
return  dArray;
}

inline 
void  DBFile::Use()
{
  Close();
}

inline DBFile::
~ DBFile()
{
  Close();
}

inline 
int  DBFile::OpenError()
{
  
return  openerror;
}

inline unsigned DBFile::FindField( 
char   * name )
{
  strcpy( TmpField.name, strupr( name ) );
  
return  dArray.Find( TmpField );
}

inline 
void  DBFile::Read()
{
  read( buf, str.lrd );
}

inline 
void  DBFile::Write()
{
  
* buf  =   32 ;
  write( buf, str.lrd );
}

inline 
char   * DBFile::Get(  char   * name,  char   * s )
{
  
return  Get( FindField( name ), s );
}

inline 
void  DBFile::Put(  char   * name,  const   char   * s )
{
  Put( FindField( name ), s );
}

inline 
void  DBFile::Put(  char   * name,  double  s )
{
  Put( FindField( name ), s );
}

inline 
double  DBFile:: operator  [] (  char   * name )
{
  
return  atof( Get( name, str._nul ) );
}

inline 
double  DBFile:: operator  [] ( unsigned i )
{
  
return  atof( Get( i, str._nul ) );
}

inline 
void  DBFile::Seekp(  long  recnum )
{
  seekp( recnum 
*  str.lrd  +  str.ldb );
}

inline 
void  DBFile::Seekg(  long  recnum )
{
  seekg( recnum 
*  str.lrd  +  str.ldb );
}

inline 
void  DBFile::Delete(  long  recnum )
{
  WriteDelFlag( recnum );
}

inline 
void  DBFile::UnDelete(  long  recnum )
{
  WriteDelFlag( recnum, 
32  );
}

inline 
int  DBFile::InRecords(  long  recnum )
{
  
return  ( recnum  >=   0   &&  recnum  <  str.records );
}

#endif

        DEFile类的CPP文件:

//  DBFILE.CPP

#include 
" dbfio.hpp "
#include 
< ctype.h >

void  DBField::SetValue(  char   * n,  int  t,  int  w,  int  d )
{
  strcpy( name, strupr( n ) );
  type 
=  toupper( t );
  width 
=  w;
  dec 
=  d;
}

void  DBFile::Init()
{
  fields 
=   0 ;
  buf 
=   0 ;
}

void  DBFile::SetFields(  int  n )
{
  fields 
=  n;
  
if ( n )
  {
    dArray.SetLimit( n );
    buf 
=   new   char [str.lrd  +   1 ];
    buf[
0 =   32 ;
    buf[str.lrd] 
=   0x1a ;
    
if ! buf  ||   ! dArray.Items() )
      openerror 
=   6 ;
  }
}

void  DBFile::Close()
{
  
if ( oldrecords  !=  str.records )
  {
    seekp( 
4  );
    write( ( 
char   *  ) & str.records,  sizeof ( unsigned  long  ) );
    oldrecords 
=  str.records;
  }
  close();
  
if ( buf )
    delete[] buf;
  dArray.RemoveAll();
  Init();
  
if ( openerror )
    setstate( ios::badbit );
}

char   * DBFile::Get( unsigned i,  char   * s )
{
  
if ( i  <  dArray.Count() )
  {
    memcpy( s, 
& buf[dArray[i].off], dArray[i].width );
    s[ dArray[i].width ] 
=   0 ;
  }
  
else
    
* =   0 ;
  
return  s;
}

DBFile
&  DBFile:: operator   >>  (  long  recnum )
{
  
if ( InRecords( recnum ) )
  {
    Seekg( recnum );
    Read();
  }
  
else
    memset( buf, 
32 , str.lrd );
  
return   * this ;
}

void  DBFile::WriteDelFlag(  long  recnum,  int  Flag )
{
  Seekp( recnum );
  write( ( 
char   *  ) & Flag,  1  );
}

//  DBFPUT.CPP

#include 
" dbfio.hpp "
#include 
< strstrea.h >
#include 
< iomanip.h >
#include 
< bcd.h >

void  DBFile::Put( unsigned i,  const   char   * s )
{
  
if ( i  <  dArray.Count() )
  {
    
int  flag  =  ios::left;
    ostrstream os( buf, str.lrd );
    os.seekp( dArray[i].off );
    
if ( dArray[i].type  ==   ' N '   ||  dArray[i].type  ==   ' F '  )
      flag 
=  ios::right;
    os 
<<  setw( dArray[i].width )  <<  setiosflags( flag )  <<  s;
  }
}

void  DBFile::Put( unsigned i,  double  val )
{
  
if ( i  <  dArray.Count() )
  {
    ostrstream os( buf, str.lrd );
    bcd a( val, dArray[i].dec );
    os.seekp( dArray[i].off );
    os 
<<  setw( dArray[i].width )  <<  setiosflags( ios::right  |  ios:: fixed  )  <<  a;
  }
}

void  DBFile::Append(  int  flag )
{
  
if ! flag )
    memset( buf, 
32 , str.lrd );
  Seekp( str.records );
  Write();
  str.records 
++ ;
}

DBFile
&  DBFile:: operator   <<  (  long  recnum )
{
  
if ( InRecords( recnum ) )
  {
    Seekp( recnum );
    Write();
  }
  
else
    Append( 
1  );
  
return   * this ;
}

//  DBFUSE.CPP

#include 
" dbfio.hpp "

DBFile::DBFile( 
const   char   * name ) : dArray(  0 1  )
{
  Init();
  Use( name );
}

void  DBFile::Use(  const   char   * name )
{
  
if ( fields )
    Close();
  open( name, ios::
in   |  ios:: out   |  ios::binary  |  ios::nocreate );
  
if ( bad() )
  {
    openerror 
=   1 ;
    
return ;
  }
  openerror 
=   0 ;
  read( ( 
char   *  ) & str,  sizeof ( DBFSTRUCT ) );
  oldrecords 
=  str.records;
  
if ( fail()  ||  str.dbfflag  !=   3  )
    openerror 
=   4 ;
  
else
    SetFields( str.ldb 
/   32   -   1  );
  
if ! openerror )
  {
    DBField Field;
    
for int  i  =   0 ; i  <  fields; i  ++  )
    {
      read( ( 
char   *  ) & Field,  sizeof ( DBField ) );
      dArray.Add( Field );
      seekg( 
32   -   sizeof ( DBField ), ios::cur );
    }
    seekg( 
1 , ios::cur );
    
if ( fail() )
      openerror 
=   4 ;
  }
  
if ( openerror )
    Close();
}

DBFile::DBFile( 
const   char   * name, DBField  * fie,  int  n ) : dArray(  0 1  )
{
  Init();
  Use( name, fie, n );
}

void  DBFile::Use(  const   char   * name, DBField  * fie,  int  n )
{
  
if ! fie  ||   ! n )
  {
    openerror 
=   3 ;
    
return ;
  }
  
if ( fields )
    Close();
  openerror 
=   0 ;
  str.lrd 
=   1 ;
  
for int  i  =   0 ; i  <  n; str.lrd  +=  fie[i].width, i  ++  )
    fie[i].off 
=  str.lrd;
  str.dbfflag 
=   3 ;
  str.date_n 
=   96 ;
  str.date_y 
=  str.date_r  =   1 ;
  str.ldb 
=  n  *   32   +   33 ;
  memset( str._nul, 
0 20  );
  open( name, ios::
in   |  ios:: out   |  ios::binary  |  ios::trunc );
  
if ( bad() )
    openerror 
=   2 ;
  
else
  {
    str.records 
=  oldrecords  =   0 ;
    write( ( 
char   *  ) & str,  sizeof ( DBFSTRUCT ) );
    SetFields( n );
    
if ! openerror )
    {
      
for int  i  =   0 ; i  <  fields; i  ++  )
      {
    write( ( 
char   *  ) & fie[i],  sizeof ( DBField ) );
    write( str._nul, 
32   -   sizeof ( DBField ) );
    dArray.Add( fie[i] );
      }
      i 
=   0x0d ;
      write( ( 
char   *  ) & i,  1  );
      
if ( fail() )
    openerror 
=   5 ;
    }
  }
  
if ( openerror )
    Close();
}
        DBFIle类所使用的动态数组模板类文件:
//  MARRAY.HPP

#ifndef __MARRAY_HPP
#define  __MARRAY_HPP

#include 
< string .h >
#include 
< iostream.h >

//  无序直接数组类模板.用户类中应定义默认构造函数和运算符 ==.

template 
< class  T >   class  MArray
{

protected :

  
char   * items;         //  动态数组指针
   int  count;         //  数组中对象个数
   int  limit;         //  数组容量
   int  delta;         //  数组增量
   int  typesize;
  MArray(){}
  
void  Init(  int int int  );
  
virtual  T &  Item(  int  index )
  {
    
return   * ( T  *  ) & items[ index  *  typesize ];
  }
  
virtual   void  Let(  int  index,  const  T *  t )
  {
    memmove( 
& items[index  *  typesize], t, typesize );
  }

public :

  
//  构造函数.参数: 数组容量(个);增加量
  MArray(  int int   =   0  );
  
~ MArray();
  
void  SetLimit(  int  );
  
//  移去一个对象,其后对象前移.参数: 数组下标
   void  Remove(  int  );
  
//  移去指定位置及其后的所有对象; 参数:数组下标
   void  RemoveAll(  int   =   0  );
  
//  增加对象到指定位置,其后对象后移,返回实际下标,出错返回 0x7fff.
  
//  参数: 数组下标;对象
   int  AddAt(  int const  T &  );
  
//  增加对象到数组尾部,返回实际的数组下标,出错返回 0x7fff.参数: 对象
   int  Add(  const  T &  );
  
//  返回动态数组指针
   char *  Items();
  
//  查找对象,返回对象下标,未找到返回 0X7FFF.参数: 对象
   int  Find(  const  T &  );
  
//  返回数组中的对象个数
   int  Count();
  
//  返回数组容量大小
   int  ArraySize();
  
//  返回对象的内存长度
   int  ObjectSize();
  
//  返回数组下标所指的对象,下标超范围时返回值不定
  T &   operator  [] (  int  );

};

template 
< class  T >  inline MArray  < T > ::MArray(  int  mLimit,  int  mDelta )
{
  Init( mLimit, mDelta, 
sizeof ( T ) );
}

template 
< class  T >  inline  void  MArray  < T > ::RemoveAll(  int  index )
{
  
if ( index  >=   0   &&  index  <  count )
    count 
=  index;
}

template 
< class  T >  inline  char *  MArray  < T > ::Items()
{
  
return  items;
}

template 
< class  T >  inline  int  MArray  < T > ::Add(  const  T &  t )
{
  
return  AddAt( count, t );
}

template 
< class  T >  inline  int  MArray  < T > ::Count()
{
  
return  count;
}

template 
< class  T >  inline  int  MArray  < T > ::ArraySize()
{
  
return  limit;
}

template 
< class  T >  inline  int  MArray  < T > ::ObjectSize()
{
  
return  typesize;
}

template 
< class  T >  inline T &  MArray  < T > :: operator  [] (  int  index )
{
  
return  Item( index );
}

#pragma  option -Jgx

template 
< class  T >
void  MArray  < T > ::Init(  int  mLimit,  int  mDelta,  int  size )
{
  items 
=   0 ;
  count 
=   0 ;
  limit 
=   0 ;
  delta 
=  mDelta;
  typesize 
=  size;
  SetLimit( mLimit );
}

template 
< class  T >  MArray  < T > :: ~ MArray()
{
  
if ( items )
    delete[] items;
}

template 
< class  T >   void  MArray  < T > ::SetLimit(  int  aLimit )
{
  
if ( aLimit  <=  limit )
    
return ;
  
if ( aLimit  >   0xfff0   /  typesize )
    aLimit 
=   0xfff0   /  typesize;
  
char   * aItems  =   new   char [aLimit  *  typesize];
  
if ( aItems )
  {
    
if ( count )
      memmove( aItems, items, count 
*  typesize );
    
if ( items )
      delete[] items;
    items 
=  aItems;
    limit 
=  aLimit;
  }
}

template 
< class  T >   void  MArray  < T > ::Remove(  int  index )
{
  
if ( index  <   0   ||  index  >=  count )
    
return ;
  count
-- ;
  
if ( count )
    memmove( 
& items[index  *  typesize],
      
& items[( index  +   1  )  *  typesize], ( count  -  index )  *  typesize );
}

template 
< class  T >   int  MArray  < T > ::AddAt(  int  index,  const  T &  t )
{
  
if ( index  <   0  )
    
return   0x7fff ;
  
if ( count  ==  limit )
    SetLimit( count 
+  delta );
  
if ( count  ==  limit )
    
return   0x7fff ;
  
if ( index  <  count )
    memmove( 
& items[( index  +   1  )  *  typesize],
         
& items[index  *  typesize],
         ( count 
-  index )  *  typesize
       );
  
else
    index 
=  count;
  Let( index, 
& t );
  count 
++ ;
  
return  index;
}

template 
< class  T >   int  MArray  < T > ::Find(  const  T &  t )
{
  
for int  i  =   0 ; i  <  count; i  ++  )
    
if ( Item( i )  ==  t )
      
return  i;
  
return   0x7fff ;
}

#pragma  option -Jg

//  有序直接数组类模板.用户类中应定义默认构造函数和运算符 == 和 <.

template 
< class  T >   class  MSArray :  public   virtual  MArray  < T >
{

protected :

  
int  index;         //  搜索时保存的数组下标值
   int  res;         //  搜索成功标记. 0 未找到匹配对象
   int  duplicates;     //  允许重复插入标记
  MSArray(){}
  
int  Search(  const  T &  key );

public :

  
//  构造函数.参数: 数组容量(个);增量;允许重复插入标记( 0 不允许重复 )
  MSArray(  int  l,  int  d  =   0 int  u  =   0  );
  
//  将对象 t 按索引方式插到数组中,返回下标.如 t 属重复对象,
  
//  重复插入标记 != 0, t 被插入到相同对象的尾部,否则返回 0x7fff.
   int  Add(  const  T &  t );
  
//  用二分法查找第一个匹配对象, 返回数组下标, 无匹配对象返回 0x7fff.
   int  Find(  const  T &  t );
  
//  在Find()基础上,查找下一匹配对象,返回数组下标,无匹配对象返回 0x7fff.
   int  FindNext();
  
//  返回使用 Find() 或 FindNext() 后 >= 关键对象的下标值
   int  IndexNum()
  {
    
return  index;
  }
};

#pragma  option -Jgx

template 
< class  T >   int  MSArray  < T > ::FindNext()
{
  
if ( res  &&  duplicates  &&   ++  index  <  count
      
&&  Item( index  -   1  )  ==  Item( index ) )
    
return  index;
  res 
=   0 ;
  
return   0x7fff ;
}

template 
< class  T >   int  MSArray  < T > ::Search(  const  T &  key )
{
  
int  l  =   0 , i;
  
int  h  =  count  -   1 ;
  res 
=   0 ;
  
while ( l  <=  h )
  {
    i 
=  ( l  +   h )  >>   1 ;
    
if ( Item( i )  <  key )
      l 
=  i  +   1 ;
    
else
    {
      h 
=  i  -   1 ;
      
if ( Item( i )  ==  key )
      {
    res 
=   1 ;
    
if ! duplicates )
      l 
=  i;
      }
    }
  }
  index 
=  l;
  
return  res;
}

template 
< class  T >   int  MSArray  < T > ::Add(  const  T &  t )
{
  
int  i  =  Find( t );
  
if ( i  ==   0x7fff  )
    i 
=  index;
  
else
  {
    
if ! duplicates )
      
return   0x7fff ;
    
for ( i  ++ ; Item( i )  ==  t  &&  i  <  count; i  ++  );
  }
  
return  AddAt( i, t );
}

template 
< class  T >   int  MSArray  < T > ::Find(  const  T &  t )
{
  
if ( Search( t ) )
    
return  index;
  
return   0x7fff ;
}

template 
< class  T >  MSArray  < T > ::MSArray(  int  l,  int  d,  int  u ) :
  MArray
< T > ( l, d ),
  duplicates( u ),
  res( 
0  )
{}

#pragma  option -Jg

//  无序间接数组类模板.退出时不删除对象本身,其余同 MArray<T> 类

template 
< class  T >   class  IMArray :  public   virtual  MArray  < T >
{

protected :

  IMArray(){}
  
virtual   void  Let(  int  i,  const  T *  t )
  {
    unsigned 
long  p  =  ( unsigned  long  )t;
    memmove( 
& items[i  *  typesize],  & p, typesize );
  }
  
virtual  T &  Item(  int  i )
  {
    
return   * ( T  *  )( * long   *  ) & items[i  *  typesize]);
  }

public :

  IMArray( 
int  Limit,  int  Delta  =   0  )
  {
    Init( Limit, Delta, 
sizeof ( T *  ) );
  }

};

//  有序间接数组类模板.退出时不删除对象本身.其余同 MSArray<T> 类

template 
< class  T >   class  IMSArray :  public  MSArray < T > public  IMArray  < T >
{

protected :

  IMSArray(){}

public :

  IMSArray( 
int  Limit,  int  Delta  =   0 int  u  =   0  ) :
    IMArray
< T > ( Limit, Delta )
  {
    duplicates 
=  u;
    res 
=   0 ;
  }

};

#endif

        对以上代码作些简单的说明:

1、DBFile类代码使用的Borland C++ 3.1编译器,其它C++编译器可能要作些修改。

2、DBFile中打开和关闭文件使用的是Use函数,没有使用Open、Create这些熟悉的函数名,是按照dBASE命令习惯命名的。

3、DEFile类没有提供DBF文件排序方法,是因为我还有个通用的 B- 树排序类,实际操作中,需要排序时,2个类结合使用的,那个类有个纯虚方法,需要继承才能使用,因为没有找到以前排序类测试代码例子,所以我正在考虑是否把那个排序类贴上来,如果贴上来,还得写一个例子,而我不用C++的时间太长,机器上又没有安装BC3.1,不知能否写好这个例子。

4、DBFile类使用了动态数组,而当时是没有STL的(即使有,我可能也不会使用,因为DOS下的资源相当紧张,而且BC3.1自身也带有数组类,和现在的STL类似,但是我嫌使用它麻烦),所以自己写了个模板类,该模板类在其它C++版本编译必须做编译选项的修改。

        声明,文章的代码是1995年前的东西,只能供初学者们借鉴参考。有错误或建议,请来信:[email protected]

        更新:今天找了个以前DBFile类的测试代码,更新在此。另外补充说明一点:这个DBFile类用今天的眼光看,是比较简陋的,其中的方法也较低阶,一般数据文件操作方法如First、Last、Next、Bof、Eof等都没有。原因是当时使用C/C++的人,一般都不大喜欢dBASE,但是为了能读取当时大量的dbf文件的数据,写一个能读dbf文件,转换成自己的文件格式的代码就不错了,我这个类在当时已经是很完善了,不仅能读写,还能创建dbf文件。通过以前这个例子,不难看出,我们当时需要的只是文件转换,或者数字字段计算功能(对数字字段使用了[]重载,可以直接以字段名或字段序号操作)[2007-9-17 13:43P]。

#include  < iostream.h >
#include 
" DBFio.hpp "

void  CreateDbf( char   * fileName)
{
    DBField fields[
3 ];
    fields[
0 ].SetValue( " Code " ' C ' 4 );
    fields[
1 ].SetValue( " Name " ' C ' 8 );
    fields[
2 ].SetValue( " Value " ' N ' 10 2 );
    DBFile Dbf;
    Dbf.Use(fileName, fields, 
3 );
    Dbf.Put(
" Code " " 0001 " );
    Dbf.Put(
" Name " " Maozefa " );
    Dbf.Put(
" Value " 12345.67 );
    Dbf.Append(
1 );
    Dbf.Put(
" Code " " 0002 " );
    Dbf.Put(
" Name " " Maojun " );
    Dbf.Put(
" Value " 78543.21 );
    Dbf.Append(
1 );
    Dbf.Use();
}

void  main()
{
    CreateDbf(
" Test.dbf " );
    DBFile dbf(
" Test.dbf " );
    
char  code[ 5 ], name[ 9 ];
    
for  ( long  i  =   0 ; i  <  dbf.Records(); i  ++ )
    {
        dbf.Read();
        dbf.Get(
" Code " , code);
        dbf.Get(
" Name " , name);
        cout 
<<  code  <<   '   '   <<  name  <<   '   '   <<  dbf[ " Value " <<  endl;
    }
    system(
" pause " );
}

        声明,文章的代码是1995年前的东西,只能供初学者们借鉴参考。有错误或建议,请来信:[email protected]

你可能感兴趣的:(ios,C++,delete,search,Class,Duplicates)