自己写的几个Linux 和 Windows 读ini配置文件的函数
cheungmine
2012
// testini.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CONF_TRUE 1
#define CONF_FALSE 0
#define CONF_MAX_BUFSIZE 1020
#define CONF_MAX_SECNAME 240
#define CONF_SEC_BEGIN 91 /* '[' */
#define CONF_SEC_END 93 /* ']' */
#define CONF_SEPARATOR 61 /* '=' */
#define CONF_NOTE_CHAR 35 /* '#' */
typedef struct _conf_position_data
{
FILE *_fp;
char _section[CONF_MAX_SECNAME+4];
char _buf[CONF_MAX_BUFSIZE+2];
} conf_position_data, *CONF_POSITION;
static char* trim(char *s, char c)
{
return (*s==0)?s:(((*s!=c)?(((trim(s+1,c)-1)==s)?s:(*(trim(s+1,c)-1)=*s,*s=c,trim(s+1,c))):trim(s+1,c)));
}
static char* ltrim(char *s, char c)
{
while(*s!=0&&*s==c){s++;}return s;
}
static char* rtrim(char *s, char c)
{
char *p=s,*q=s;while(*p!=0){if(*p!=c){q=p;q++;}p++;}if(q!=s)*q=0;return s;
}
static char* dtrim(char *s, char c)
{
return rtrim(ltrim(s, c), c);
}
static int readln(FILE *fp, char *buf, int bufsize)
{
int i, j;
char ch;
for (i=0, j=0; i<bufsize; j++)
{
if (fread(&ch, sizeof(char), 1, fp) != 1)
{
/* read error */
if (feof(fp) != 0)
{
if (j==0)
{
return -1; /* end file */
}
else
{
break;
}
}
return -2;
}
else
{
/* read a char */
if (ch==10 || ch==0) /* 10='\n' */
{
/* read a line ok */
break;
}
if (ch==12 || ch==0x1A) /* 12='\f' */
{
buf[i++]=ch;
break;
}
if (ch != 13) /* '\r' */
{
buf[i++]=ch;
}
}
if (i==bufsize)
{
return -3; /* exceed max chars */
}
}
buf[i] = 0;
return i;
}
static int splitpair(char *buf, char sep, char **key, char **val)
{
char *at = strchr(buf, sep);
if (at==NULL)
{
return CONF_FALSE;
}
*at++ = 0;
*key = buf;
*key = dtrim(dtrim(*key, 32), 9);
*val = at;
*val = dtrim(dtrim(dtrim(*val, 32), 9), 34); /* '\"' */
if (*key != 0 && *val != 0)
{
return CONF_TRUE;
}
return CONF_FALSE;
}
CONF_POSITION ConfOpenFile(const char *conf)
{
CONF_POSITION cpos;
FILE *fp = fopen(conf, "rb");
if (fp==NULL)
{
return NULL;
}
cpos = (CONF_POSITION) malloc(sizeof(_conf_position_data));
memset(cpos, 0, sizeof(_conf_position_data));
cpos->_fp = fp;
return cpos;
}
void ConfCloseFile(CONF_POSITION cpos)
{
fclose(cpos->_fp);
free(cpos);
}
char *ConfGetNextPair(CONF_POSITION cpos, char **key, char **val)
{
char *start;
int nch;
for (;;)
{
nch = readln(cpos->_fp, cpos->_buf, CONF_MAX_BUFSIZE);
if (nch < 0)
{
return NULL;
}
start = dtrim(dtrim(cpos->_buf, 32), 9);
if (*start == CONF_NOTE_CHAR) /* # */
{
continue;
}
nch = strlen(start);
if (nch > 2)
{
if (nch <= CONF_MAX_SECNAME && *start==CONF_SEC_BEGIN && *(start+nch-1)==CONF_SEC_END)
{
/* find a section */
*(start+nch-1) = 0;
start++;
strcpy(cpos->_section, start);
continue;
}
if (splitpair(start, CONF_SEPARATOR, key, val)==CONF_TRUE)
{
return start;
}
}
}
return NULL;
}
char *ConfGetFirstPair(CONF_POSITION cpos, char **key, char **val)
{
if (cpos==NULL)
{
return NULL;
}
rewind(cpos->_fp);
return ConfGetNextPair(cpos, key, val);
}
const char *ConfGetSection(CONF_POSITION cpos)
{
return cpos->_section;
}
int ConfReadValue(const char *confFile, const char *sectionName, const char *keyName, char *value)
{
char *key;
char *val;
CONF_POSITION cpos = ConfOpenFile(confFile);
if (cpos != NULL)
{
while (ConfGetNextPair(cpos, &key, &val) != NULL)
{
if (strcmp(ConfGetSection(cpos), sectionName)==0 && strcmp(key, keyName)==0)
{
/* find section and key */
strcpy(value, val);
ConfCloseFile(cpos);
return CONF_TRUE;
}
}
ConfCloseFile(cpos);
}
return CONF_FALSE;
}
#define confile "c:/dev/tmp/conf.ini"
// Test App:
//
int main(int argc, char* argv[])
{
char value[CONF_MAX_BUFSIZE];
if (ConfReadValue(confile, "mpmgr", "timo", value))
{
printf("[mpmgr]\ntimo=%s\n", value);
}
return 0;
}
测试的ini/conf文件如下:
#[section]
#key=value
[mpsrvr]
ip = 192.168.63.100
port = 5899
[mpmgr]
ip = 192.78.90
timo = 6
city = shang hai
pathfile = "/usr/local/lib/mpsocket/mpsrvr ddd"