⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ini.c

📁 其他人不需帐号就可自由下载此源码 其他人不需帐号就可自由下载此源码
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#include "ini.h"

#define INI_MAX_LENGTH 1024

static int  split_keyval(char *line, char **key, char **val);
static int  read_line(FILE *fp, char *buf, int maxlen);

static int  read_file(FILE *fp, INI_FILE *fb);
static void free_file(INI_FILE *fb);

static int  key_val(INI_FILE   *fb, const char *sec, const char *key, char *buf, int len);
static int  write_file(FILE *fp, INI_FILE *fb);
static int  set_key_val(INI_FILE *fb, char *sec, char *key, char *buf);


static char *trim(char *buf);
static char *ltrim(char *buf);
static char *rtrim(char *buf);
static void print_file(INI_FILE *fb);


/*

读取键值

*/
int ReadConfigKey(char *fname, char *sec, char *key, char *val) {
	
	FILE *fp;
	INI_FILE fb;

	int rb = 0;
	if ((fp = fopen(fname, "rb")) != NULL) {
		if (read_file(fp, &fb)) {
			if (key_val(&fb, sec, key, val, sizeof(val))) {
				rb = 1;
			}
		}
		fclose(fp);
		free_file(&fb);
	}
	return rb;
}

/*

修改键值

*/
int WriteConfigKey(char *fname, char *sec, char *key, char *val) {
	
	int rb = 0;
	FILE *fp;
	INI_FILE fb;
	
	if ((fp = fopen(fname, "rb")) != NULL) {
		if (read_file(fp, &fb)) {
			fclose(fp);
			if (set_key_val(&fb, sec, key, val)) {
				if ((fp = fopen(fname, "wb")) != NULL) {
					if (write_file(fp, &fb)) {
						rb = 1;
					}
				}      
			}
		} 
		fflush(fp);
		fclose(fp);    
		free_file(&fb);
	}
	return rb;
}

/**
* 
* 读取配置文件的内容到内存,并生成链表,以便操作如果读取成
* 功则返回1否则返回0,注意该过程没有对文件作任何修改的
* 操作,只是把文件内容按照段以及一行一行的格式读入内存
*/
static int read_file(FILE *fp, INI_FILE *fb) {
	
	int n;
	INI_SECTION *cur_sec,  *pre_sec;
	INI_KEY_VALUE *cur_key, *pre_key;
	char buf[INI_MAX_LENGTH + 1], tmp[INI_MAX_LENGTH + 1];
	char *bp, *key, *val;

	fb->sections = NULL;
	fb->keyval   = NULL;
	pre_sec = NULL;
	pre_key = NULL;
	while(1) {
		n = read_line(fp, buf, INI_MAX_LENGTH);
		if (n < -1 ) return 0;

		//读取文件结束
		if (n < 0) return 1;
		strcpy(tmp, buf);
		n = (int)strlen(trim(buf));
		if( n > 2 && ((buf[0] == '[' && buf[n-1] != ']') || 
			(buf[0] == '{' && buf[n-1] != '}'))) { //非法段
				return 0;
		}
		bp = (char *)calloc(n + 1, 1);
		if (bp == NULL) {
			return 0;
		}
		strcpy(bp, tmp);

		if (n > 2 && (buf[0] == '[' || buf[0] == '{')) { //如果是段
			cur_sec = (INI_SECTION *)calloc(sizeof(INI_SECTION), 1);
			if (cur_sec == NULL) {
				return 0;
			} else {
				cur_sec->keyval = NULL;
				cur_sec->next = NULL;
				cur_sec->line = bp;
				if (fb->sections == NULL) {
					fb->sections = cur_sec;
				} else {
					pre_sec->next = cur_sec;
				}
				pre_sec = cur_sec;
				//新的一个段开始需要置NULL
				pre_key = NULL;
			}
		} else { //如果是键值或空行以及说明信息
			//检查文件内容的合法性
			if (strlen(trim(tmp)) > 0) {
				if (tmp[0] != ';') {
					if (split_keyval(tmp, &key, &val)) {
						if (strlen(trim(key)) == 0) {
							return 0;
						} 
					}
				}
			}
			cur_key = (INI_KEY_VALUE *)calloc(sizeof(INI_KEY_VALUE), 1);
			if (cur_key == NULL) {
				return 0;
			}
			cur_key->next = NULL;
			cur_key->line = bp;
			if (fb->sections == NULL) { //如果段为空
				if (pre_key == NULL) {    //如果还没有关键字(最前面的配置信息可以没有段名称)
					fb->keyval = cur_key;
				} else {
					pre_key->next = cur_key;
				}
			} else {//段不为空,加入到
				if (pre_key == NULL) {
					pre_sec->keyval = cur_key;
				} else {
					pre_key->next = cur_key;
				}
			}
			pre_key = cur_key;
		}
	}
	return 1;
}


/*

把配置信息写入到文件中

*/
static int write_file(FILE *fp, INI_FILE *fb) {
	
	INI_SECTION *pre_sec;
	INI_KEY_VALUE *pre_key;
	char temp[1024];
	
	if (fb != NULL) {

		pre_key = fb->keyval;
		while(pre_key != NULL) {
			strcpy(temp, pre_key->line);
			strcat(temp, "\r\n");
			if (fwrite(temp, strlen(temp), 1, fp) != 1) {
				return 0;
			}
			pre_key = pre_key->next;
		}

		pre_sec = fb->sections;
		while(pre_sec != NULL) {
			strcpy(temp, pre_sec->line);
			strcat(temp, "\r\n");
			if (fwrite(temp, strlen(temp), 1, fp) != 1) {
				return 0;
			}
			pre_key = pre_sec->keyval;
			while(pre_key != NULL) {
				strcpy(temp, pre_key->line);
				strcat(temp, "\r\n");
				if (fwrite(temp, strlen(temp), 1, fp) != 1) {
					return 0;
				}
				pre_key = pre_key->next;
			}
			pre_sec = pre_sec->next;
		}
	}
	fflush(fp);
	return 1;
}


/**
*
*  把字符串从等号分开得到一个key和相应的值 
*  xxx    =   yyyyyyyy 
*   |      |   | 
*   k1     k2  i 
*
*/
static int split_keyval(char *line, char **key, char **val) { 
	char *pt;
	int  n;
	
	if((n = (int)strlen(line)) < 1) 
		return 0;
	pt = strchr(line, '=');
	if (pt != NULL) {
		*val = pt + 1;
		*key = line;
		*pt = '\0';
	} else {
		return 0;
	}
	return 1;
} 


static int key_val(INI_FILE *fb, const char *sec, const char *key, char *buf, int len) {
	
	int n;
	INI_SECTION *pre_sec;
	INI_KEY_VALUE *pre_key;
	char *mkey;
	char *val;
	char temp[1024];

	if (fb == NULL || len < 1) 
		return 0;
	if (sec == NULL) {
		pre_key = fb->keyval;
		while(pre_key != NULL) {
			strcpy(temp, pre_key->line);
			n = (int)strlen(trim(temp));
			if (n > 0 && temp[0] != ';') {
				if (split_keyval(temp, &mkey, &val)) {
					n = (int)strlen(trim(mkey));
					if (n == 0) {//配置文件有错误
						return 0;
					} else {
						if (strcmp(mkey, key) == 0) {
							strcpy(buf, trim(val));
							return 1;
						}
					}
				}
			}
			pre_key = pre_key->next;
		}
		return 0;
	} else {
		pre_sec = fb->sections;
		while(pre_sec != NULL) {
			strcpy(temp, pre_sec->line);
			temp[strlen(temp) - 1] = '\0';
			if (strcmp(temp+1, sec) == 0) {
				break;
			}
			pre_sec = pre_sec->next;
		}
		if (pre_sec == NULL) return 0;
		pre_key = pre_sec->keyval;
		while(pre_key != NULL) {
			strcpy(temp, pre_key->line);
			n = (int)strlen(trim(temp));
			if (n > 0 && temp[0] != ';') {
				if (split_keyval(temp, &mkey, &val)) {
					n = (int)strlen(trim(mkey));
					if (n == 0) {//配置文件有错误
						return 0;
					} else {
						if (strcmp(mkey, key) == 0) {
							strcpy(buf, trim(val));
							return 1;
						}
					}
				}
			}
			pre_key = pre_key->next;
		}
		return 0;
	}
	return 0;
}


static int set_key_val(INI_FILE *fb, char *sec, char *key, char *buf ) {
	
	int n;
	INI_SECTION *pre_sec;
	INI_KEY_VALUE *pre_key;
	char *mkey;
	char *val;
	char temp[1024];
	char *pt;

	if (fb == NULL) 
		return 0;
	if (sec == NULL) {
		pre_key = fb->keyval;
		while(pre_key != NULL) {
			strcpy(temp, pre_key->line);
			n = (int)strlen(trim(temp));
			if (n > 0 && temp[0] != ';') {
				if (split_keyval(temp, &mkey, &val)) {
					n = (int)strlen(trim(mkey));
					if (n == 0) {//配置文件有错误
						return 0;
					} else {
						if (strcmp(mkey, key) == 0) {
							pt = (char *)calloc(strlen(key) + 4 + strlen(buf), sizeof(char));
							if (pt == NULL) return 0;
							sprintf(pt, "%s = %s", mkey, buf);
							free(pre_key->line);
							pre_key->line = pt;
							return 1;
						}
					}
				}
			}
			pre_key = pre_key->next;
		}
		return 0;
	} else {
		
		pre_sec = fb->sections;
		while(pre_sec != NULL) {
			strcpy(temp, pre_sec->line);
			temp[strlen(temp) - 1] = '\0';
			if (strcmp(temp+1, sec) == 0) {
				break;
			}
			pre_sec = pre_sec->next;
		}
		if (pre_sec == NULL) return 0;
		pre_key = pre_sec->keyval;
		while(pre_key != NULL) {
			strcpy(temp, pre_key->line);
			n = (int)strlen(trim(temp));
			if (n > 0 && temp[0] != ';') {
				if (split_keyval(temp, &mkey, &val)) {
					n = (int)strlen(trim(mkey));
					if (n == 0) {//配置文件有错误
						return 0;
					} else {
						if (strcmp(mkey, key) == 0) {
							pt = (char *)calloc(strlen(mkey) + 4 + strlen(buf), sizeof(char));
							if (pt == NULL) return 0;
							sprintf(pt, "%s = %s", mkey, buf);
							free(pre_key->line);
							pre_key->line = pt;
							return 1;
						}
					}
				}
			}
			pre_key = pre_key->next;
		}
		return 0;
	}
	return 0;
}




/**
*
* 释放内存空闲,注意先释放文件头部的空间,
* 接着一个段一个段的释放
*
*/
static void free_file(INI_FILE *fb) {
	
	INI_SECTION *pre_sec;
	INI_KEY_VALUE *pre_key;
	
	if (fb != NULL) {
		pre_key = fb->keyval;
		while(pre_key != NULL) {
			fb->keyval = pre_key->next;
			if (pre_key->line != NULL) {
				free(pre_key->line);
			}
			free(pre_key);
			pre_key = fb->keyval;
		}
		pre_sec = fb->sections;
		while(pre_sec != NULL) {
			fb->sections = pre_sec->next;
			pre_key = pre_sec->keyval;
			while(pre_key != NULL) {
				pre_sec->keyval = pre_key->next;
				if (pre_key->line != NULL) {
					free(pre_key->line);
				}
				free(pre_key);
				pre_key = pre_sec->keyval;
			}
			if(pre_sec->line != NULL) {
				free(pre_sec->line);
			}
			free(pre_sec);
			pre_sec = fb->sections;
		}
	}
}

/**
*
* 读取文本文件的一行到buffer缓冲区(通用函数)
* 缓冲区的数据不含有行结束标识符号
* FILE *fp, 文件句柄 
* char *buffer 缓冲区
* int maxlen 读取的最大数目
* 返回: 读取的字符数 -1出错误
*
*/
static int read_line(FILE *fp, char *buf, int maxlen) { 
	
	int  i, j; 
	
	i = 0;	
	buf[0] = '\0';
	if(!feof(fp)) {
		if (fgets(buf, maxlen, fp) != NULL) {
			i = (int)strlen(buf);
		} else {
			if(feof(fp)) {
				i = (int)strlen(buf);
				if (i == 0) return -1;
			} else {
				return -2;
			}
		}
	} else {
		return -1;
	}
	for(j = i - 1; j > -1; j--) {
		if (buf[j] == '\r' || buf[j] == '\n')
			buf[j] ='\0'; 
	}
	return i; 
} 



/**
* 去掉字符串的空格
*/
static char *trim(char *buf) {
	char *p;
	p = rtrim(buf);
	p = ltrim(buf);
	return p;
}

static char *ltrim(char *buf) {
	strrev(buf);
	rtrim(buf);
	strrev(buf);
	return buf;
}

static char *rtrim(char *buf) {
	int  n, j;
	n = (int)strlen(buf) - 1;
	for (j = n; j > -1; j--) {
		if (*(buf + j) == ' ') {
			*(buf + j) = '\0';
		} else {
			break;
		}
	}
	return buf;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -