iniclass.h
#ifndef INICLASS_H
#define INICLASS_H
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SECTION_MAX_LEN 256
#define STRVALUE_MAX_LEN 256
#define LINE_CONTENT_MAX_LEN 256
#define READ_STR_ERR 0
#define READ_STR_OK 1
#define XXX printf("===< %s %d >===\n", __FUNCTION__, __LINE__);
using namespace std;
class INICLASS
{
public:
explicit INICLASS(const string& name);
~INICLASS();
void readFile();
void writeFile();
void IniReadValue(char* section, char* key, char* val, const char* file);
int readStringValue(const char* section, char* key, char* val, const char* file);
int readIntValue(const char* section, char* key, const char* file);
void IniWriteValue(const char* section, char* key, char* val, const char* file);
int writeStringVlaue(const char* section, char* key, char* val, const char* file);
int writeIntValue(const char* section, char* key, int val, const char* file);
private:
int m_fd;
string m_path;
/*private:*/
};
#include <map>
#include <string>
using namespace std;
#define CONFIGLEN 256
enum INI_RES
{
INI_SUCCESS, //成功
INI_ERROR, //普通错误
INI_OPENFILE_ERROR, //打开文件失败
INI_NO_ATTR //无对应的键值
};
// 子键索引 子键值
typedef map<std::string,std::string> KEYMAP;
// 主键索引 主键值
typedef map<std::string,KEYMAP> MAINKEYMAP;
// config 文件的基本操作类
class CIni
{
public:
// 构造函数
CIni();
// 析够函数
virtual ~CIni();
public:
//获取整形的键值
int GetInt(const char* mAttr, const char* cAttr );
//获取键值的字符串
char *GetStr(const char* mAttr, const char* cAttr );
// 打开config 文件
INI_RES OpenFile(const char* pathName, const char* type);
// 关闭config 文件
INI_RES CloseFile();
protected:
// 读取config文件
INI_RES GetKey(const char* mAttr, const char* cAttr, char* value);
protected:
// 被打开的文件局柄
FILE* m_fp;
public:
char m_szKey[ CONFIGLEN ];
MAINKEYMAP m_Map;
};
#endif // INICLASS_H
iniclass.cpp
#include "iniclass.h"
#include <stdio.h>
INICLASS::INICLASS(const string& name)
{
// m_path = name;
// m_fd = open(m_path.c_str(), O_RDWR, 0644);
}
INICLASS::~INICLASS()
{
}
void INICLASS::readFile()
{
}
void INICLASS::writeFile()
{}
void INICLASS::IniReadValue(char* section, char* key, char* val, const char* file)
{
XXX
FILE* fp;
int i = 0;
int lineContentLen = 0;
int position = 0;
char lineContent[LINE_CONTENT_MAX_LEN];
bool bFoundSection = false;
bool bFoundKey = false;
fp = fopen(file, "r");
if(fp == NULL)
{
printf("%s: Opent file %s failed.\n", __FILE__, file);
return;
}
XXX
while(feof(fp) == 0)
{
memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
if((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
{
continue;
}
//check section
if(strncmp(lineContent, section, strlen(section)) == 0)
{
bFoundSection = true;
//printf("Found section = %s\n", lineContent);
while(feof(fp) == 0)
{
memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
XXX
//check key
if(strncmp(lineContent, key, strlen(key)) == 0)
{
bFoundKey = true;
lineContentLen = strlen(lineContent);
//find value
for(i = strlen(key); i < lineContentLen; i++)
{
if(lineContent[i] == '=')
{
position = i + 1;
break;
}
}
if(i >= lineContentLen) break;
XXX
printf("%d\n", position);
strncpy(val, lineContent + position, strlen(lineContent + position));
lineContentLen = strlen(val);
for(i = 0; i < lineContentLen; i++)
{
if((lineContent[i] == '\0') || (lineContent[i] == '\r') || (lineContent[i] == '\n'))
{
val[i] = '\0';
break;
}
}
}
else if(lineContent[0] == '[')
{
break;
}
}
break;
}
}
if(!bFoundSection){printf("No section = %s\n", section);}
else if(!bFoundKey){printf("No key = %s\n", key);}
fclose(fp);
}
int INICLASS::readStringValue(const char* section, char* key, char* val, const char* file)
{
char sect[SECTION_MAX_LEN];
//printf("section = %s, key = %s, file = %s\n", section, key, file);
if (section == NULL || key == NULL || val == NULL || file == NULL)
{
printf("%s: input parameter(s) is NULL!\n", __func__);
return READ_STR_ERR;
}
memset(sect, 0, SECTION_MAX_LEN);
sprintf(sect, "[%s]", section);
//printf("reading value...\n");
IniReadValue(sect, key, val, file);
return READ_STR_OK;
}
int INICLASS::readIntValue(const char* section, char* key, const char* file)
{
char strValue[STRVALUE_MAX_LEN];
memset(strValue, '\0', STRVALUE_MAX_LEN);
if(readStringValue(section, key, strValue, file) != READ_STR_OK)
{
printf("%s: error", __func__);
return 0;
}
return(atoi(strValue));
}
void INICLASS::IniWriteValue(const char* section, char* key, char* val, const char* file)
{
FILE* fp;
int i = 0, n = 0, err = 0;
int lineContentLen = 0;
int position = 0;
char lineContent[LINE_CONTENT_MAX_LEN];
char strWrite[LINE_CONTENT_MAX_LEN];
bool bFoundSection = false;
bool bFoundKey = false;
memset(lineContent, '\0', LINE_CONTENT_MAX_LEN);
memset(strWrite, '\0', LINE_CONTENT_MAX_LEN);
n = sprintf(strWrite, "%s=%s\n", key, val);
fp = fopen(file, "r+");
if(fp == NULL)
{
printf("%s: Opent file %s failed.\n", __FILE__, file);
return;
}
while(feof(fp) == 0)
{
memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
if((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
{
continue;
}
//check section
if(strncmp(lineContent, section, strlen(section)) == 0)
{
bFoundSection = true;
while(feof(fp) == 0)
{
memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
//check key
if(strncmp(lineContent, key, strlen(key)) == 0)
{
bFoundKey = true;
printf("%s: %s=%s\n", __func__, key, val);
fseek(fp, (0-strlen(lineContent)),SEEK_CUR);
err = fputs(strWrite, fp);
if(err < 0){printf("%s err.\n", __func__);}
break;
}
else if(lineContent[0] == '[')
{
break;
}
}
break;
}
}
if(!bFoundSection){printf("No section = %s\n", section);}
else if(!bFoundKey){printf("No key = %s\n", key);}
fclose(fp);
}
int INICLASS::writeStringVlaue(const char* section, char* key, char* val, const char* file)
{
char sect[SECTION_MAX_LEN];
//printf("section = %s, key = %s, file = %s\n", section, key, file);
if (section == NULL || key == NULL || val == NULL || file == NULL)
{
printf("%s: input parameter(s) is NULL!\n", __func__);
return READ_STR_ERR;
}
memset(sect, '\0', SECTION_MAX_LEN);
sprintf(sect, "[%s]", section);
IniWriteValue(sect, key, val, file);
}
int INICLASS::writeIntValue(const char* section, char* key, int val, const char* file)
{
char strValue[STRVALUE_MAX_LEN];
memset(strValue, '\0', STRVALUE_MAX_LEN);
sprintf(strValue, "%-4d", val);
writeStringVlaue(section, key, strValue, file);
}
/******************************************************************************
* 功 能:构造函数
* 参 数:无
* 返回值:无
* 备 注:
******************************************************************************/
CIni::CIni( )
{
memset( m_szKey,0,sizeof(m_szKey) );
m_fp = NULL;
}
/******************************************************************************
* 功 能:析构函数
* 参 数:无
* 返回值:无
* 备 注:
******************************************************************************/
CIni::~CIni()
{
m_Map.clear();
}
/******************************************************************************
* 功 能:打开文件函数
* 参 数:无
* 返回值:
* 备 注:
******************************************************************************/
INI_RES CIni::OpenFile(const char* pathName, const char* type)
{
string szLine,szMainKey,szLastMainKey,szSubKey;
char strLine[ CONFIGLEN ] = { 0 };
KEYMAP mLastMap;
int nIndexPos = -1;
int nLeftPos = -1;
int nRightPos = -1;
m_fp = fopen(pathName, type);
if (m_fp == NULL)
{
printf( "open inifile %s error!\n",pathName );
return INI_OPENFILE_ERROR;
}
m_Map.clear();
while( fgets( strLine, CONFIGLEN,m_fp) )
{
szLine.assign( strLine );
//删除字符串中的非必要字符
nLeftPos = szLine.find("\n" );
if( string::npos != nLeftPos )
{
szLine.erase( nLeftPos,1 );
}
nLeftPos = szLine.find("\r" );
if( string::npos != nLeftPos )
{
szLine.erase( nLeftPos,1 );
}
//判断是否是主键
nLeftPos = szLine.find("[");
nRightPos = szLine.find("]");
if( nLeftPos != string::npos && nRightPos != string::npos )
{
szLine.erase( nLeftPos,1 );
nRightPos--;
szLine.erase( nRightPos,1 );
m_Map[ szLastMainKey ] = mLastMap;
mLastMap.clear();
szLastMainKey = szLine ;
}
else
{
//是否是子键
if( nIndexPos = szLine.find("=" ),string::npos != nIndexPos)
{
string szSubKey,szSubValue;
szSubKey = szLine.substr( 0,nIndexPos );
szSubValue = szLine.substr( nIndexPos+1,szLine.length()-nIndexPos-1);
mLastMap[szSubKey] = szSubValue ;
}
else
{
//TODO:不符合ini键值模板的内容 如注释等
}
}
}
//插入最后一次主键
m_Map[ szLastMainKey ] = mLastMap;
return INI_SUCCESS;
}
/******************************************************************************
* 功 能:关闭文件函数
* 参 数:无
* 返回值:
* 备 注:
******************************************************************************/
INI_RES CIni::CloseFile()
{
if (m_fp != NULL)
{
fclose(m_fp);
m_fp = NULL;
}
return INI_SUCCESS;
}
/******************************************************************************
* 功 能:获取[SECTION]下的某一个键值的字符串
* 参 数:
* char* mAttr 输入参数 主键
* char* cAttr 输入参数 子键
* char* value 输出参数 子键键值
* 返回值:
* 备 注:
******************************************************************************/
INI_RES CIni::GetKey(const char* mAttr, const char* cAttr, char* pValue)
{
KEYMAP mKey = m_Map[ mAttr ];
string sTemp = mKey[ cAttr ];
strcpy( pValue, sTemp.c_str() );
return INI_SUCCESS;
}
/******************************************************************************
* 功 能:获取整形的键值
* 参 数:
* cAttr 主键
* cAttr 子键
* 返回值:正常则返回对应的数值 未读取成功则返回0(键值本身为0不冲突)
* 备 注:
******************************************************************************/
int CIni::GetInt(const char* mAttr, const char* cAttr )
{
int nRes = 0;
memset( m_szKey,0,sizeof(m_szKey) );
if( INI_SUCCESS == GetKey( mAttr,cAttr,m_szKey ) )
{
nRes = atoi( m_szKey );
}
return nRes;
}
/******************************************************************************
* 功 能:获取键值的字符串
* 参 数:
* cAttr 主键
* cAttr 子键
* 返回值:正常则返回读取到的子键字符串 未读取成功则返回"NULL"
* 备 注:
******************************************************************************/
char *CIni::GetStr(const char* mAttr, const char* cAttr )
{
memset( m_szKey,0,sizeof(m_szKey) );
if( INI_SUCCESS != GetKey( mAttr,cAttr,m_szKey ) )
{
strcpy( m_szKey,"NULL" );
}
return m_szKey;
}
main.cpp
#include "iniclass.h"
int main()
{
CIni* intClass = NULL;
intClass = new CIni();
intClass->OpenFile("./test.ini", "r+");
intClass->GetStr("Section1","key2");
printf("pVal1: %s\n", intClass->m_szKey);
intClass->GetInt("Section2","key1");
printf("nKey: %d\n", intClass->m_szKey);
return 0;
}