ini.cpp
资源名称:读写文件.rar [点击查看]
上传用户:whyxdz88
上传日期:2007-07-26
资源大小:4k
文件大小:15k
源码类别:
文件操作
开发平台:
Visual C++
- // Ini 相关函数
- //------------------------------------------------------------------
- // 包含
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <io.h>
- #include <fcntl.h>
- #include <assert.h>
- #include "ini.h"
- //-------------------------------------------------------------------
- // 对外接口
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------------------------
- // 初始化/析构释放
- //-------------------------------------------------------------------------------------
- CIni::CIni()
- {
- m_lDataLen = 0;
- m_strData = NULL;
- IndexNum = 0;
- IndexList = NULL;
- }
- CIni::CIni(char *filename)
- {
- m_lDataLen = 0;
- m_strData = NULL;
- IndexNum = 0;
- IndexList = NULL;
- Open(filename);
- }
- CIni::~CIni()
- {
- if( m_lDataLen != 0 )
- {
- SAFE_DELETE( m_strData );
- m_lDataLen = 0;
- }
- if( IndexNum != 0 )
- {
- SAFE_DELETE( IndexList );
- IndexNum = 0;
- }
- }
- //-------------------------------------------------------------------------------------
- // 功能:读入配置
- // 入口:文件全路径;出口:无
- //-------------------------------------------------------------------------------------
- bool CIni::Open(char *filename)
- {
- strcpy(m_strFileName, filename);
- SAFE_FREE( m_strData );
- int fh;
- fh = _open( filename, _O_RDONLY ); // 只读方式
- if( fh== -1 )
- m_lDataLen = -1;
- m_lDataLen = _filelength(fh); // 获取文件长度
- _close(fh);
- if( m_lDataLen > 0 )// 文件存在
- {
- m_strData = new char[m_lDataLen];// 申请空间
- FILE *fp;
- fp=fopen(filename, "rb");
- fread(m_strData, m_lDataLen, 1, fp);// 读数据
- fclose(fp);
- InitIndex(); // 初始化索引
- return true;
- }
- else // 文件不存在
- {
- m_lDataLen=1;
- m_strData = new char[m_lDataLen];
- memset(m_strData, 0, 1);
- InitIndex();
- }
- return false;
- }
- //-------------------------------------------------------------------------------------
- // 功能:释放内存
- // 入口:无;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::Close()
- {
- if( m_lDataLen != 0 )
- {
- SAFE_DELETE( m_strData );
- m_lDataLen = 0;
- }
- if( IndexNum != 0 )
- {
- SAFE_DELETE( IndexList );
- IndexNum = 0;
- }
- }
- //-------------------------------------------------------------------------------------
- // 功能:写入文件
- // 入口:文件全路径;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::Save(char *filename)
- {
- if( filename==NULL )
- filename=m_strFileName;
- FILE *fp;
- fp=fopen(filename, "wb");
- fwrite(m_strData, m_lDataLen, 1, fp);
- fclose(fp);
- }
- //-------------------------------------------------------------------------------------
- // 功能:读一字符串数据
- // 入口:段名,键名;出口:字符数据
- //-------------------------------------------------------------------------------------
- char *CIni::ReadText(char *index, char *name)
- {
- int n=FindIndex(index); // 找索引
- int m=FindData(n, name); // 找键名
- return ReadText(m); // 获得键值
- }
- //-------------------------------------------------------------------------------------
- // 功能:读一整数
- // 入口:段名,键名;出口:整数
- //-------------------------------------------------------------------------------------
- int CIni::ReadInt(char *index, char *name)
- {
- int n=FindIndex(index); // 找索引
- int m=FindData(n, name); // 找键名
- char *str=ReadText(m); // 获得键值
- int ret=atoi(str); // 字符转化为整数
- free(str);
- return ret;
- }
- //-------------------------------------------------------------------------------------
- // 功能:写一字符串数据
- // 入口:段名,键名,键值;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::Write(char *index, char *name, char *string)
- {
- int n=FindIndex(index);
- if( n == -1 ) // index不存在,新建一个索引
- {
- AddIndex(index); // 添加索引
- n=FindIndex(index); // 找到索引位置
- n=GotoLastLine(index); // 取得它的下一行
- AddData(n, name, string); //在当前位置n加一个数据
- return ;
- }
- int m=FindData(n, name);// index索引存在
- if( m==-1 ) // 索引存在,键名不存在,新建数据
- {
- n=GotoLastLine(index);
- AddData(n, name, string); // 在当前位置n加一个数据
- return ;
- }
- // 键名存在
- ModityData(n, name, string); // 修改一个数据
- return;
- }
- //-------------------------------------------------------------------------------------
- // 功能:写一整数
- // 入口:段名,键名,键值;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::Write(char *index, char *name, int num)
- {
- char string[32];
- sprintf(string, "%d", num);
- int n=FindIndex(index);
- if( n == -1 ) // 新建索引
- {
- AddIndex(index); // 添加一个索引
- n=FindIndex(index);
- n=GotoLastLine(index); // 获得本段最后一行
- AddData(n, name, string); // 在当前位置n加一个数据
- return;
- }
- int m=FindData(n, name); // 存在索引,找到键名首位置
- if( m==-1 ) // 键名不存在,新建数据
- {
- n=GotoLastLine(index);
- AddData(n, name, string); //在当前位置n加一个数据
- return;
- }
- // 存在数据
- ModityData(n, name, string); //修改一个数据
- return;
- }
- //-------------------------------------------------------------------------------------
- // 功能:删除一段
- // 入口:段名;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::DeleteIndex(char *index)
- {
- // char *name;
- int n = FindIndex(index); // 找索引
- if( n == -1 )
- return; // 没有此段返回
- n = GotoNextLine(n); // 获得首键名地址
- // name = ReadHeadName(n); // 获得=之前的数据
- // Write(index, name, 0);
- // n = GotoNextLine(n);
- int next = GotoLastLine(index); // 获得本段最后一行
- if( m_strData[next] == EOF )
- {
- m_lDataLen = n; // 更新长度
- m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存
- InitIndex(); // 更新索引
- return;
- }
- char *temp=new char[m_lDataLen-next];
- memcpy(temp, &m_strData[next], m_lDataLen-next); // 把next至最后的这一段长度内容保存
- memcpy(&m_strData[n], temp, m_lDataLen-next); // 把next至最后的这一段长度内容向前移
- m_lDataLen -= next-n; // 更新长度
- m_strData = (char *)realloc(m_strData, m_lDataLen);
- // 重新分配内存
- InitIndex(); // 更新索引
- }
- //-------------------------------------------------------------------------------------
- // 功能:删除一行
- // 入口:段名;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::DeleteName(char *index,char *name)
- {
- int m;
- int n = FindIndex(index); // 找索引
- if( n == -1 )
- return; // 没有此段返回
- n = FindHead(n, name); // 找键名
- if( n == -1 ) // 键名不存在返回
- return;
- m = GotoNextLine(n); // 获得下一行的起始位置
- char *temp=new char[m_lDataLen-m];
- memcpy(temp, &m_strData[m], m_lDataLen-m); // 把m至最后的这一段长度内容保存
- memcpy(&m_strData[n], temp, m_lDataLen-m); // 把m至最后的这一段长度内容向前移
- m_lDataLen -= m-n; // 更新长度
- m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存
- InitIndex(); // 更新索引
- }
- //--------------------------------------------------------------------------
- // 内部函数
- //--------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------
- // 功能:计算出所有的索引位置
- // 入口:无;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::InitIndex()
- {
- IndexNum=0;
- for(int i=0; i<m_lDataLen; i++)
- {
- if( m_strData[i]=='[' && ( m_strData[i-1]=='n' || i==0 ) )// 找到一个
- IndexNum++;
- }
- SAFE_DELETE( IndexList );
- if( IndexNum>0 )
- IndexList=new int[IndexNum];// 申请内存
- int n=0;
- for(i=0; i<m_lDataLen; i++)
- {
- if( m_strData[i]=='[' && ( m_strData[i-1]=='n' || i==0 ) )
- {
- IndexList[n]=i+1; // 记录位置
- n++;
- }
- }
- }
- //-------------------------------------------------------------------------------------
- // 功能:返回指定段名位置
- // 入口:指定段名;出口:首位置
- //-------------------------------------------------------------------------------------
- int CIni::FindIndex(char *string)
- {
- for(int i=0; i<IndexNum; i++)
- {
- char *str=ReadText( IndexList[i] );
- if( strcmp(string, str) == 0 )
- {
- SAFE_FREE( str );
- return IndexList[i];
- }
- SAFE_FREE( str );
- }
- return -1;
- }
- //-------------------------------------------------------------------------------------
- // 功能:返回指定数据的位置
- // 入口:索引,指定键名;出口:键名首位置
- //-------------------------------------------------------------------------------------
- int CIni::FindHead(int index, char *string)
- {
- int p=index; // 指针
- char *name;
- while(1)
- {
- p = GotoNextLine(p); // 获得下一行起始位置
- name = ReadHeadName(p); // 获得=之前的数据
- if( strcmp(string, name)==0 )
- {
- SAFE_FREE( name );
- return p;
- }
- SAFE_FREE( name );
- if( p>=m_lDataLen || m_strData[p] == '[' ) return -1;
- }
- return -1;
- }
- //-------------------------------------------------------------------------------------
- // 功能:返回指定数据的位置
- // 入口:索引,指定键名;出口:键名=号的位置
- //-------------------------------------------------------------------------------------
- int CIni::FindData(int index, char *string)
- {
- int p=index; // 指针
- char *name;
- while(1)
- {
- p = GotoNextLine(p); // 获得下一行起始位置
- if( p>=m_lDataLen || m_strData[p] == '[' ) return -1;
- name = ReadDataName(p); // 获得=之前的数据
- if( strcmp(string, name)==0 )
- {
- SAFE_FREE( name );
- return p;
- }
- SAFE_FREE( name );
- }
- return -1;
- }
- //-------------------------------------------------------------------------------------
- // 功能:获得下一行起始位置
- // 入口:位置;出口:下一行首位置
- //-------------------------------------------------------------------------------------
- int CIni::GotoNextLine(int p)
- {
- for(int i=p; i<m_lDataLen; i++)
- {
- if( m_strData[i]=='n' )
- return i+1;
- }
- return i;
- }
- //-------------------------------------------------------------------------------------
- // 功能:在指定位置读一数据名称
- // 入口:行首位置;出口:=号后的字符串
- //-------------------------------------------------------------------------------------
- char *CIni::ReadDataName(int &p)
- {
- char chr;
- char *Ret;
- int m=0;
- Ret=new char[MAX_PATH];
- memset(Ret, 0, MAX_PATH);
- for(int i=p; i<m_lDataLen; i++)
- {
- chr = m_strData[i];
- if( chr == 'r' || chr == '=' || chr == ';' )// 结束
- {
- p=i+1;
- return Ret;
- }
- Ret[m]=chr;
- m++;
- }
- return Ret;
- }
- //-------------------------------------------------------------------------------------
- // 功能:在指定位置读一数据名称
- // 入口:行首位置;出口:=号后的字符串
- //-------------------------------------------------------------------------------------
- char *CIni::ReadHeadName(int &p)
- {
- char chr;
- char *Ret;
- int m=0;
- Ret=new char[MAX_PATH];
- memset(Ret, 0, MAX_PATH);
- for(int i=p; i<m_lDataLen; i++)
- {
- chr = m_strData[i];
- if( chr == 'r' || chr == '=' || chr == ';' )// 结束
- {
- return Ret;
- }
- Ret[m]=chr;
- m++;
- }
- return Ret;
- }
- //-------------------------------------------------------------------------------------
- // 功能:在指定位置读一字符串,p为索引位置
- // 入口:行首位置;出口:=号前的字符串
- //-------------------------------------------------------------------------------------
- char *CIni::ReadText(int p)
- {
- char chr;
- char *Ret;
- int n=p, m=0;
- int LineNum = GotoNextLine(p) - p + 1;
- Ret=new char[LineNum];
- memset(Ret, 0, LineNum);
- for(int i=0; i<m_lDataLen-p; i++)
- {
- chr = m_strData[n];
- if( chr == ';' || chr == 'r' || chr == 't' || chr == ']' )// 结束
- {
- return Ret;
- }
- Ret[m]=chr;
- m++;
- n++;
- }
- return Ret;
- }
- //-------------------------------------------------------------------------------------
- // 功能:加入一个索引
- // 入口:索引;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::AddIndex(char *index)
- {
- char str[MAX_PATH];
- memset(str, 0, MAX_PATH);
- sprintf(str,"rn[%s]rn",index);
- m_strData = (char *)realloc(m_strData, m_lDataLen+strlen(str)); // 重新分配内存
- sprintf(&m_strData[m_lDataLen], "%s", str); // 写入索引
- m_lDataLen+=strlen(str); // 长度指向最后
- InitIndex(); // 重建索引
- }
- //-------------------------------------------------------------------------------------
- // 功能:在当前位置加入一个数据
- // 入口:当前行的首点,键名,键值;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::AddData(int p, char *name, char *string)
- {
- char *str;
- int len;
- str=new char[2*MAX_PATH];
- memset(str, 0, 2*MAX_PATH);
- sprintf(str,"%s=%srn",name,string);
- len=strlen(str);
- m_strData = (char *)realloc(m_strData, m_lDataLen+len); // 重新分配内存
- char *temp=new char[m_lDataLen-p];
- memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存
- memcpy(&m_strData[p+len], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移
- memcpy(&m_strData[p], str, len); // 在p存入字符串
- m_lDataLen+=len; // 长度增加
- SAFE_DELETE(temp);
- SAFE_DELETE(str);
- InitIndex(); // 更新索引
- }
- //-------------------------------------------------------------------------------------
- // 功能:在当前位置修改一个数据的值
- // 入口:当前行的首点,键名,键值;出口:无
- //-------------------------------------------------------------------------------------
- void CIni::ModityData(int p, char *name, char *string)
- {
- int n=FindData(p, name);
- char *t=ReadText(n);
- p=n+strlen(t); // p指向本行最后,n指向=号后
- if( strlen(t)>0 ) free(t);
- int newlen=strlen(string);
- int oldlen=p-n;
- m_strData = (char *)realloc(m_strData, m_lDataLen+newlen-oldlen); // 重新分配内存
- char *temp=new char[m_lDataLen-p];
- memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存
- memcpy(&m_strData[n+newlen], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移
- memcpy(&m_strData[n], string, newlen); // 在n存入新字符串
- m_lDataLen+=newlen-oldlen; // 更新长度
- SAFE_DELETE( temp );
- InitIndex(); // 更新索引
- }
- //-------------------------------------------------------------------------------------
- // 功能:把指针移动到本INDEX的最后一行
- // 入口:索引点;出口:段内最后一行首位置
- //-------------------------------------------------------------------------------------
- int CIni::GotoLastLine(char *index)
- {
- int n=FindIndex(index);
- n=GotoNextLine(n);
- while(1)
- {
- if( m_strData[n] == 'r' || m_strData[n] == EOF || m_strData[n] == -3 || m_strData[n] == ' ' || m_strData[n] == '/' || m_strData[n] == 't' || m_strData[n] == 'n' )
- {
- return n;
- }
- else
- {
- n=GotoNextLine(n);
- if( n >= m_lDataLen ) return n;
- }
- }
- }