glib使用平衡二叉树实现读配置文件

.h

#ifndef ALAN_LIBCONFIG_H
#define ALAN_LIBCONFIG_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_LEN 128 // 文件行长度
#define SECT_LEN 64 // 节点名称长度
#define VINT_LEN 64 // 整型数值长度
#define VCHR_LEN 64 // 字符型值长度


typedef struct _item_
{
    char            *key;
    char            *value;
    char            *section;
    struct _item_   *next;

} config_item;

typedef struct {
    char            *fname;
    struct _item_   *header;
    struct _item_   *tailer;
    int          length;
} config;

typedef struct _ListNode                // 链表节点结构体
{
    int         itemcount;              // 一段里面有多个元素,即有多少个<key,value>对
    GTree*      ptree;                  // 二叉树指针
    char        sectionname[100];           // 段名
}ListNode;




config *config_form_open(const char *fname);



void config_from_close(config *pini);

#endif//ALAN_LIBCONFIG_H

.c

#include "config.h"

static void list_append(config *pconfig,
                        char *key,
                        char *value,
                        char *section
                        )
{
    config_item *item = (config_item *)malloc(sizeof(config_item));

    item->section = section;
    item->key = key;
    item->value = value;
    item->next = NULL;
    if (!pconfig->tailer)
    {
        pconfig->header = pconfig->tailer = item;
    }
    else
    {
        pconfig->tailer->next = item;
        pconfig->tailer = item;
    }
    pconfig->length += 1;

    return;
}


config *config_from_open(const char *fname)
{
    config *pconfig;
    FILE *fp = fopen(fname,"r");
    char buffer[LINE_LEN];
    char *p;
    char *s;
    char sect[SECT_LEN];
    char *section;
    char *key;
    char *value;

    if (!fp)
    {
        return NULL;
    }
    pconfig = (config *)malloc(sizeof(config));
    pconfig->fname = (char *)malloc(strlen(fname)+1);
    strcpy(pconfig->fname,fname);
    pconfig->length = 0;
    pconfig->header = pconfig->tailer = NULL;

    while (!feof(fp))
    {
        if (!fgets(buffer,LINE_LEN,fp))
            break;
        for (p=buffer; ' '==*p||'\t'==*p; p++);
        if ('#'==*p || '\n'==*p || '\r'==*p)
        {
            continue;
        }
        else if ('<' == *p)
        {
            for (p++; ' '==*p||'\t'==*p; p++);
            for (s=p; ' '!=*p&&'\t'!=*p&&'>'!=*p; p++);
            *p = 0;
            strcpy(sect,s);
        }
        else
        {
            for (; ' '==*p||'\t'==*p; p++);
            for (s=p; ' '!=*p&&'\t'!=*p&&'='!=*p&&':'!=*p; p++);
            {
                *p = 0;
            }
            key = (char *)malloc(strlen(s)+1);
            {
                strcpy(key,s);
            }
            for (p++; ' '==*p||'\t'==*p||'='==*p||':'==*p; p++);
            for (s=p; '#'!=*p&&';'!=*p&&'\n'!=*p&&'\r'!=*p; p++);
            {
                *p = 0;
            }
            for (p=s+strlen(s)-1; ' '==*p; *p=0,p--);
            {
                value = (char *)malloc(strlen(s)+1);
            }
            strcpy(value,s);

            section = (char *)malloc(strlen(sect)+1);
            strcpy(section,sect);

            list_append(pconfig,key,value,section);
        }
    }
    fclose(fp);

    return (config*)pconfig;
}



void config_from_free(config *pconfig)
{
    config_item *p = pconfig->header;
    config_item *temp;

    if (!p)
    {
        return;
    }
    while (p)
    {
        free(p->key);
        free(p->value);
        free(p->section);
        temp = p;
        p = p->next;
        free(temp);
    }

    free(pconfig->fname);
    free(pconfig);

    return;
}

main

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>

#include "config_manager.h"


gboolean myPrint(gpointer key, gpointer value, gpointer fmt)
{
    if(key != NULL && value != NULL)
    {
        printf("%s,%s\n",(char *)key, (char*)value);
    }
    return FALSE;
}

int main()
{
    config *pconfig; //创建链表1

    //char *path = "small_config.txt";
    char *path = "config.txt";

    pconfig = config_from_open(path);

    if (!pconfig)
    {
        printf("load config faild.\n");
        return 0;
    }
    printf("文件长度:%d\n",pconfig->length);
    // printf("打开文件成功!\n");

    //创建链表2
    //GList *list = (GList*)malloc(sizeof(GList));
    GList *list = NULL;

    //链表2的节点
    ListNode *listNode = NULL;

    //迭代器
    config_item *it = pconfig->header; 

    //保存上一链表1节点中的段名
    char tmpsectionname[100]; 
    memset(tmpsectionname, 0, sizeof(tmpsectionname));

    while(1)
    {
        if(strcmp(tmpsectionname, it->section) != 0)
        {
            //把上一段保存起来
            if(NULL != listNode)
            {
                //printf("开始保存上一段的内容\n");
                //获取二叉树中的节点个数
                listNode->itemcount = g_tree_nnodes(listNode->ptree);
                //将上一个链表2节点插入到链表中
                list = g_list_append(list, (gpointer)listNode);
                //printf("保存上一段的内容,成功!\n");
                listNode = NULL;
            }

            memset(tmpsectionname, 0, sizeof(tmpsectionname));
            strcpy(tmpsectionname, it->section);

            //创建一个链表节点
            listNode = (ListNode*)malloc(sizeof(ListNode));

            //设置段名
            memset(listNode->sectionname, 0, sizeof(listNode->sectionname));
            strcpy(listNode->sectionname, it->section);

            //创建一棵树
            listNode->ptree = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
        }

        // 读取一段下面的内容
        // printf("向二叉树插入数据\n");
        // printf("%s = %s\n", (char *)((gpointer)it->key), (char *)((gpointer)it->value));

        g_tree_insert(listNode->ptree, (gpointer)it->key, (gpointer)it->value);

        //printf("打印出树中的数据:%s\n", (char*)g_tree_lookup(listNode->ptree, (gpointer)it->key));


        if(pconfig->tailer == it)
        {
            //printf("开始保存上一段的内容\n");
            list = g_list_append(list, (gpointer)listNode);
            listNode->itemcount = g_tree_nnodes(listNode->ptree);
            //printf("保存上一段的内容, 成功! \n");
            break;
        }
        it = it->next;

    }

    //读取链表2内容
    int i = 0;
    for(i = 0; i < g_list_length(list); i++)
    {
        ListNode *temp = (ListNode *)g_list_nth_data(list, (guint)i);
        if(temp == NULL)
        {
            printf("temp is NULL!\n");
            break;
        }
        else
        {           
            printf("%s\n", temp->sectionname);
            //g_tree_foreach(temp->ptree, (GTraverseFunc)myPrint,NULL);
            printf("item143 is %s\n",(char *)g_tree_lookup(temp->ptree,"item143"));
            printf("stringitem_965 is %s\n",(char *)g_tree_lookup(temp->ptree,"stringitem_965"));
        }

    }

    // 释放资源
    for(i = 0; i < g_list_length(list); i++)
    {
        ListNode *temp = (ListNode *)g_list_nth_data(list, i);
        if(NULL != temp->ptree)
        {
            g_tree_destroy(temp->ptree); //释放二叉树
            temp->ptree = NULL;
        }
    }

    if(NULL != list)
    {
        g_list_free(list); //释放链表
        free(list);
        list = NULL;
    }

    // 关闭文件,释放链表1
    config_from_free(pconfig);
    //printf("释放资源成功!\n");

    return 0;
}

功能主要在main函数实现 没有设计函数 有人全部设计完了 可以在楼下贴出来 或者发我邮箱 927214501@qq.ocm 多谢

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/qq_36088602/article/details/71224565
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞