ini文件的读取

  • ini文件:每行末尾有换行符 + 每个section之间有一空行

  • 文件
[0]
id=0
key2=def.key
start=456
end=78

[1]
id=1
key1=abc.key
start=123
end=456
  • 代码示例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdarg.h>

#define LINE_SIZE 128
void get_string_from_ini2(char *title0, char *key, char *filename, char* result)
{
    char lineBuffer[LINE_SIZE] = {'0'};
    char reslt[LINE_SIZE];
    int ofst = 0;
    FILE* fp = fopen(filename, "r");
    int flag = 0;

    char title[16] = {'0'};
    snprintf(title, 16, "[%s]\n", title0);
// read fp until end
    while (!feof(fp))
    {
        // read a char to lineBuffer 
        int chr = fgetc(fp);
        lineBuffer[ofst++] = chr;

        //get a line data
        if (chr == '\n') {
            printf("=== got line [%s]\n", lineBuffer);
            // find title
            if (!strcmp(title, lineBuffer)) {
                // printf("11111 [%s]\n", title);
                flag = 1;
                ofst = 0;
                memset(lineBuffer, 0x00, LINE_SIZE);
                continue;
            }
            // find key-value
            if (flag == 1) {
                if(strstr(lineBuffer, key)) { // find key
                    
                    char* data = strstr(lineBuffer, "=");
                    // printf("====== [%s] \n value [%s]\n", lineBuffer, data);
                    if(data) { strcpy(result, data+1); }  // 拷贝 = 后的数据
                    printf("got data===[%s]\n", result);
                    return;
                }
            }
            // 两个section间的空行
            if (lineBuffer[0] == '\n') {
                flag = 0;
            }
            ofst = 0;
            memset(lineBuffer, 0x00, LINE_SIZE);
        }
    }
}




int main(int argc, char **argv)
{

char relt[32] = {"0"};
// get_string_from_ini2("1", "key0", argv[1], relt);
get_string_from_ini2("1", "key1", argv[1], relt);


}
  • 考虑到需要修改ini特定key的value,于是用一个链表来存一个ini文件,实现了对这个文件的读取,修改。
  • 大体思路:一个字节字节的读,然后把数据写入单链表,再找到需要修改的session和key,再去修改链表的值,最后去把所有的链表数据覆盖写入文件。
  • ini测试文件如下
[1]
id=0
key=key_0.key

[2]
id=3
key=key_x.key
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
节点模板
[0]            session[8]
id=0           id[4]
key=def.key    key[16]
*/

typedef struct Data {
	char session[8];
    char id[4];
    char key[16];
} SessionData;
 
//单向链表
typedef struct singleListNode
{
    SessionData data;
    struct singleListNode* next;
}singleListNode;
 

static singleListNode *headNode = NULL, *tailNode = NULL;
static int singleListNodeCount = 0;

// 读到filename文件的title中的key的value 
char key_list[2][16] ={
	"id",
	"key",
};

#define LINE_SIZE 1024
#define LIST_LEN (sizeof(key_list)/ sizeof(key_list[0]))

//链表在last和next之间插入一个节点
singleListNode* insertListNode(singleListNode* last, singleListNode* next)
{
    // generate a node
    singleListNode* newNode = (singleListNode*) malloc(sizeof(singleListNode));
    // new node be pointed by last node
    if (last != NULL) {last->next = newNode;}
    // new node point to next node 
    newNode->next = next;

    singleListNodeCount++;
    return newNode;
}
 
//链表删除数据
void del_ListNode(singleListNode* node)
{
    if (node == headNode) {
        singleListNode* tmp = headNode->next;
        free(headNode);
        headNode = tmp;

        if(--singleListNodeCount == 0)
        {
            headNode = NULL;
            tailNode = NULL;
        }
        return;
    }

    singleListNode* next;
    singleListNode* last = NULL, *nodeTmp=NULL;
    {
        // get next node
        next = node->next;

        // get last node
        for (nodeTmp = headNode; nodeTmp != NULL; (nodeTmp = nodeTmp->next))
        {
            if (nodeTmp->next == node) 
                last = nodeTmp;
        }
    
        // link last node to next node
        if (last)
            last->next = next;
    }
    // update tailnode val
    if (node == tailNode) {
        tailNode = last;
    }
    free(node);
    singleListNodeCount--;
    return;
}

void printfData(SessionData* data) {
	char rslt[1024];
	snprintf(rslt, 1024, "session = [%s] id =[%s] key =[%s]",
	            data->session, data->id, data->key);
    printf("%s\n", rslt);
}

// print all list val
void printfListVal()
{
    singleListNode* node;
    int a = 0;
    printf("===============head %p count %d\n", headNode, singleListNodeCount);
    for (node = headNode; node != NULL; (node = node->next))
    {
        printf("node = [%p] ", node);
        printfData(&node->data);
    }
    for (node = headNode; node != NULL; (node = node->next))
    {
        printf("node %p-->%p--\n", node, node->next);
    }
    printf("===============tail %p\n", tailNode);
}

void create_NodeatTail(SessionData data)
{
    singleListNode* tmp = NULL;
    if (!headNode) {
        headNode = insertListNode(NULL, NULL);
        tailNode = headNode;
        tmp = headNode;
    } else {
        tmp = insertListNode(tailNode, NULL);
        tailNode = tmp;
    }
    memcpy(&tmp->data, &data, sizeof(SessionData));
}

// 在last和next之间插入节点并赋值
void create_NodeafterNode(SessionData* data, singleListNode* last, singleListNode* next)
{
    singleListNode* tmp = insertListNode(last, next);
    memcpy(&tmp->data, data, sizeof(SessionData));
}

void get_string_from_ini(char *title0, char *key, char *filename, char* result)
{
    char lineBuffer[LINE_SIZE] = {'0'};
    char reslt[LINE_SIZE];
    int ofst = 0;
    FILE* fp = fopen(filename, "r");
    int flag = 0;

    char title[16] = {'0'};
    snprintf(title, 16, "[%s]\n", title0);
// read fp until end
    while (!feof(fp))
    {
        // read a char to lineBuffer 
        int chr = fgetc(fp);
        lineBuffer[ofst++] = chr;

        //get a line data
        if (chr == '\n') {
            printf("=== got line [%s]\n", lineBuffer);
            // find title
            if (!strcmp(title, lineBuffer)) {
                // printf("11111 [%s]\n", title);
                flag = 1;
                ofst = 0;
                memset(lineBuffer, 0x00, LINE_SIZE);
                continue;
            }
            // find key-value
            if (flag == 1) {
                if(strstr(lineBuffer, key)) { // find key
                    
                    char* data = strstr(lineBuffer, "=");
                    // printf("====== [%s] \n value [%s]\n", lineBuffer, data);
                    if(data) { strcpy(result, data+1); }  // 拷贝 = 后的数据
                    printf("got data===[%s]\n", result);
                    return;
                }
            }
            // 两个section间的空行
            if (lineBuffer[0] == '\n') {
                flag = 0;
            }
            ofst = 0;
            memset(lineBuffer, 0x00, LINE_SIZE);
        }
    }
}

void data_set(int i, char* value, SessionData* data)
{
    printf(" len =%ld\n", strlen(value));
	switch (i)
	{
	case 0:
		strncpy(data->id, value, 4);
		break;
	case 1:
		strncpy(data->key, value, 16);
		break;
	default:
		break;
	}

}

int get_SessionData(FILE* fp, SessionData* node)
{
	int ofst = 0;
	char line[128] = {'\0'};
    char title[8];
    int size_cnt = -1;
    while (!feof(fp))
    {
        // read a char to lineBuffer 
        int chr = fgetc(fp);
		line[ofst++] = chr;
		if (chr == '\n') {
            size_cnt += strlen(line);

			if (line[0] == '\n') { // 两个session间的空格
                // ftell(fp);
                return 0;
			} else if (line[0] == '[' && line[ofst-2] == ']') { // get title
				strncpy(node->session, &line[1], (ofst-3));
			} else {
                // 替换 '\n' 为 '\0'
                if (ofst > 1) {
                    line[ofst-1]= '\0';
                }
                // 得到所有的key-value到 node
				for (int i = 0; i < LIST_LEN; i++)
				{
					char* ptr = strstr(line, key_list[i]);
					if (ptr) {
                        char* data = strstr(line, "=");
                        printf("key [%s] data[%s]",  key_list[i], data+1);
						data_set(i, data + 1, node);
                        break;
					}
				}
			}
			memset(line, 0x00, sizeof(line));
			ofst = 0;
		}
	}
    return size_cnt;




}

//根据fp不同选择插入模式
void update_FileBySessionData(FILE* fp, SessionData* dataSession)
{

    char rslt[1024] = {'\0'};

    {
        // write session
        snprintf(rslt, 1024, "[%s]\n"
                                "id=%s\n"
                                "key=%s\n"
                                "\n",
                    dataSession->session, dataSession->id, dataSession->key);
        fprintf(fp, "%s", rslt);
        printf("%s", rslt);
    }

}

// updata data after session which find by listtable
void updateFile_AfterSession(FILE* fp, SessionData* data, char* session)
{

// update data to linktable
    singleListNode* node;
    printfListVal();
    for (node = headNode; node != NULL; (node = node->next))
    {
        if (!strcmp(node->data.session, session))
        {
            create_NodeafterNode(data, node, node->next);
            break;
        }
    }
    printfListVal();
// write linktable to file
    for (node = headNode; node != NULL; (node = node->next))
        update_FileBySessionData(fp, &node->data);
}

int main()
{

    char* filename;
//从ini文件读数据:链表的形式
    {
        /*
        [0]
        id=0
        key=key_0.key

        [1]
        id=1
        key=key_s.key

        [2]
        id=3
        key=key_x.key

        */
//         FILE* fp = fopen("Conf.ini", "r");
//         SessionData tmp;  
// 		memset(&tmp, 0x00, sizeof(tmp));
// //把数据放入链表
//         while (!feof(fp))
//         {
//             // 读一个session并把数据放入tmp
//             get_SessionData(fp, &tmp);  // &tmp = 0x7fffffffe050
//             // 创建链表节点
//             create_NodeatTail(tmp);
//     		memset(&tmp, 0x00, sizeof(tmp));
//         }
// //删除链表
//         printfListVal();
//         del_ListNode(headNode);
//         printfListVal();
//         del_ListNode(tailNode);
//         printfListVal();
//         del_ListNode(tailNode);
//         printfListVal();
    }

//从ini文件读数据:解析字符串
	{
	    //char result[32];
        //get_string_from_ini("0", "id", "config.ini", result);
	}

// 往ini文件写数据
    {
        // SessionData tmp1 = {
        //     .session = "3",

        //     .id = "4",
        //     .key = "key_9.key",
        // };

        // create_NodeatTail(tmp1);

        // // FILE* fp = fopen("Conf.ini", "r+"); // 不覆盖
        // // FILE* fp = fopen("Conf.ini", "w"); // 覆盖写到开头
        // FILE* fp = fopen("Conf.ini", "a+"); // 不覆盖写到末尾

        // update_FileBySessionData(fp, &tmp1);
    }

// 在某个节点之后写入session
    {

        FILE* fp = fopen("Conf.ini", "r");
        SessionData tmp;  
		memset(&tmp, 0x00, sizeof(tmp));
//把数据放入链表
        while (!feof(fp))
        {
            // 读一个session并把数据放入tmp
            if (-1 != get_SessionData(fp, &tmp)) {
                // 创建链表节点
                create_NodeatTail(tmp);
                memset(&tmp, 0x00, sizeof(tmp));
            }
        }
        printfListVal();
        fclose(fp);

        FILE* fp2 = fopen("Conf.ini", "w+");
// 在session [1]之后插入 tmp1
        SessionData tmp1 = {
            .session = {'5', '\0', '\0'},
            .id = {'4', '\0', '\0'},
            .key = {'k', 'e', 'y', '_', '9', '.', 'k', 'e', 'y', '\0', '\0'},
        };
        updateFile_AfterSession(fp2, &tmp1, "1");
        fclose(fp2);

    }
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值