?? ini.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 + -