C实现键值对(Map功能)

本文深入解析了kv.h与kv.c两个文件的代码实现,详细阐述了如何通过这些文件进行文件读取、映射和表操作。包括文件初始化、获取基名、值和索引等关键步骤,以及释放内存和打印表信息的函数实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kv.h代码如下:

#define UT_BASE_NODE_T(TYPE) \
    struct {          \
        TYPE *start;  \
        TYPE *end;    \
    }
typedef struct _kv
{
    char *k;
    char *v;
    unsigned int klen;
    unsigned int vlen;
    unsigned int id;
    struct _kv *next;
}kv;
typedef struct _map
{
    char *base;
    unsigned int id;
    unsigned int   kv_count; //number of maps
    UT_BASE_NODE_T(struct _kv) bt;
    struct _map *next;
}map;
typedef struct _table
{
    unsigned int map_count;
    UT_BASE_NODE_T(struct _map) info;
}table;
/*
 * read map info from file 
 */
extern table *Map_init(const char *path);
/*
 * acroding a index of key,get a basename, key,value
 */
extern char **Get_bkv(table *tb,int map_id,int key_index);
/*
 *
 */
extern void Map_free(table  *tb);
/*
 *
 */
extern void *Map_prt(table *tb);
kv.c代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kv.h"
#define MAX  1024
#define CFLAG  10
#define L  91
#define R  93
char *trim(char *msg)
{
    
    int msg_len=strlen(msg);
    char *trunc=strchr(msg,CFLAG);
    int trunc_len=strlen(trunc);
    *(msg+msg_len-trunc_len)='\0';
    //printf("%s,len=%d\n",msg,strlen(msg));
    return msg;
}
inline static int lr(const char *msg)
{
    int len=strlen(msg);
    return (*(msg+0)==L)&&(*(msg+len-1)==R);
}
char *base(char *name)
{
    char *tmp=(name+1);
    *(tmp+strlen(tmp)-1)='\0';
    return tmp;
}
table *Map_init(const char *path)
{
    FILE *fp=fopen(path,"r+");
    char buf[MAX];
    map *res=NULL;
    table *tb=NULL;
    int map_count=0;
    int kvid=0,mapid=0;
    kv *kv_head=NULL;
    if(!fp)
    {
        fprintf(stderr,"fopen %s is null\n",path);
        return tb;
    }
    tb=(table *)malloc(sizeof(table));
    if(!tb)
        return tb;
    tb->map_count=0;
    while((fgets(buf,MAX,fp))!=NULL)
    {
        char *s=trim(buf);
        int len=strlen(s);
        int flag=lr(s);
        if(flag==1)
        {
           char *name=base(s);
           int name_len=strlen(name);
           printf("%s,flag=%d\n",name,flag);
           if(res==NULL)
           {
               res=(map *)malloc(sizeof(map));
               tb->map_count=0;
               tb->info.start=res;
           }
           else
           {
               map *cur=(map *)malloc(sizeof(map));
               res->next=cur;
               res=cur;
           }
           mapid++;
           tb->info.end=res;
           tb->map_count++;
           res->id=mapid;
           res->base=(char *)malloc(name_len+1);
           res->kv_count=0;
           memset(res->base,'\0',name_len+1);
           memcpy(res->base,name,name_len);
           kvid=0;
           kv_head=NULL;
        }
        else
        {
            char *k=strtok(s,"=");
            char *v=strtok(NULL,"=");
            int k_len=strlen(k);
            int v_len=strlen(v);
            if(kv_head==NULL)
            {
                kv_head=(kv *)malloc(sizeof(kv));
                res->bt.start=kv_head;
            }
            else
            {
                kv *cur=(kv *)malloc(sizeof(kv));
                kv_head->next=cur;
                kv_head=cur;
            }
            kv_head->klen=k_len;
            kv_head->vlen=v_len;
           // printf("k = %s[%d], v= %s[%d]\n",k,kv_head->klen,v,kv_head->vlen);
            res->kv_count++;
            kvid++;
            res->bt.end=kv_head;
            kv_head->k=(char *)malloc(k_len+1);
            kv_head->v=(char *)malloc(v_len+1);
            memset(kv_head->k,'\0',k_len);
            memset(kv_head->v,'\0',v_len);
            memcpy(kv_head->k,k,k_len);
            memcpy(kv_head->v,v,v_len);
            kv_head->id=kvid;
        }
    }
    if(fp!=NULL)
    {
        fclose(fp);
    }
    //printf(" map header=%p\n",head);
    return tb;
}
void *Map_prt(table *tb)
{
    if(tb!=NULL)
    {
        map *mp=tb->info.start;
        printf("tb->map_count =%d,map start=%p,map end=%p\n",tb->map_count,tb->info.start,tb->info.end);
        printf("#################################################\n");
        printf(" map->kv.start=%p,map->kv.end=%p\n",mp->bt.start,mp->bt.end);
        while(mp!=NULL)
        {
            printf("map addr =%p,next=%p,map base =%s, map id=%d\n",mp,mp->next,mp->base,mp->id);
            kv *t=mp->bt.start;
            while(t!=NULL)
            {
                printf("    kv addr=%p,next=%p\n",t,t->next);
                printf("        kv_id=%d,k =%s(k len=%d),v =%s(v len=%d)\n",t->id,t->k,t->klen,t->v,t->vlen);
                t=t->next;
            }
            mp=mp->next;
        }
    }
}
char **Get_bkv(table *tb,int map_id,int key_index)
{
    char *s[3]={NULL};
    char **bkv=NULL;
    if(!tb)
    {
        fprintf(stderr," table map is null\n");
        return bkv;
    }
    if(!(map_id&&key_index))
    {
        fprintf(stderr," map id and key index must > 0\n");
        return bkv;
    }
    if(map_id>tb->map_count)
    {
        fprintf(stderr," map id over number of map count\n");
        return bkv;
    }
    map *mp=tb->info.start;
    kv *t=NULL;
    while(mp!=NULL)
    {
        if(key_index>mp->kv_count)
        {
            fprintf(stderr," key index over number of keys\n");
            break;
        }
        if(mp->id==map_id)
        {
            t=mp->bt.start;
            while(t!=NULL)
            {
                if(t->id==key_index)
                {
                    s[0]=mp->base;
                    s[1]=t->k;
                    s[2]=t->v;
                    bkv=(char **)&s;
                    break;
                }
                t=t->next;
            }
        }
        mp=mp->next;
    }
    //bkv=(char **)&s;
    return bkv;
}
void Map_free(table  *tb)
{
    if(!tb){fprintf(stderr," table is null\n");exit(0);}
    map *head=tb->info.start;
    while(head!=NULL)
    {
        map *maptmp=head->next;
        kv *kvtmp=head->bt.start;
        while(kvtmp!=NULL)
        {
            kv *tmp=kvtmp->next;
            printf(" free kv =%p\n",kvtmp);
            free(kvtmp->k);
            free(kvtmp->v);
            kvtmp->k=NULL;
            kvtmp->v=NULL;
            free(kvtmp);
            kvtmp=tmp;
        }
        kvtmp=NULL;
        printf("free map =%p\n",head);
        free(head);
        head=maptmp;
    }
    head=NULL;
    free(tb);
    tb=NULL;
}
int main(void)
{
    char *path="./1.txt";
    table *tb=Map_init(path);
    Map_prt(tb);
    int i,j;
    for(i=1;i<=tb->map_count;i++)
    {
        for(j=1;j<=40;j++)
        {
            char **s=Get_bkv(tb,i,j);
            if(s!=NULL)
            {
                printf("base = %s,key =%s,value=%s\n",s[0],s[1],s[2]);
            }
        }
        printf("        ######################          \n");
    }
    Map_free(tb);
    return 0;
}
运行结果:

[mysql@centos2 mysql_tool]$ ./kv
master,flag=1
slave1,flag=1
tb->map_count =2,map start=0xaa2270,map end=0xaa24f0
#################################################
 map->kv.start=0xaa22c0,map->kv.end=0xaa2480
map addr =0xaa2270,next=0xaa24f0,map base =master, map id=1
    kv addr=0xaa22c0,next=0xaa2330
        kv_id=1,k =master_user(k len=11),v =root(v len=4)
    kv addr=0xaa2330,next=0xaa23a0
        kv_id=2,k =master_password(k len=15),v =root(v len=4)
    kv addr=0xaa23a0,next=0xaa2410
        kv_id=3,k =master_port(k len=11),v =3306(v len=4)
    kv addr=0xaa2410,next=0xaa2480
        kv_id=4,k =master_socket(k len=13),v =/tmp/mysql.sock(v len=15)
    kv addr=0xaa2480,next=(nil)
        kv_id=5,k =master_host(k len=11),v =localhost(v len=9)
map addr =0xaa24f0,next=(nil),map base =slave1, map id=2
    kv addr=0xaa2540,next=0xaa25b0
        kv_id=1,k =slave1_user(k len=11),v =root(v len=4)
    kv addr=0xaa25b0,next=0xaa2620
        kv_id=2,k =slave1_password(k len=15),v =root(v len=4)
    kv addr=0xaa2620,next=0xaa2690
        kv_id=3,k =slave1_port(k len=11),v =3306(v len=4)
    kv addr=0xaa2690,next=0xaa2700
        kv_id=4,k =slave1_socket(k len=13),v =/tmp/mysql.sock(v len=15)
    kv addr=0xaa2700,next=(nil)
        kv_id=5,k =slave1_host(k len=11),v =localhost(v len=9)
base = master,key =master_user,value=root
base = master,key =master_password,value=root
base = master,key =master_port,value=3306
base = master,key =master_socket,value=/tmp/mysql.sock
base = master,key =master_host,value=localhost
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
        ######################          
base = slave1,key =slave1_user,value=root
base = slave1,key =slave1_password,value=root
base = slave1,key =slave1_port,value=3306
base = slave1,key =slave1_socket,value=/tmp/mysql.sock
base = slave1,key =slave1_host,value=localhost
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
 key index over number of keys
        ######################          
 free kv =0xaa22c0
 free kv =0xaa2330
 free kv =0xaa23a0
 free kv =0xaa2410
 free kv =0xaa2480
free map =0xaa2270
 free kv =0xaa2540
 free kv =0xaa25b0
 free kv =0xaa2620
 free kv =0xaa2690
 free kv =0xaa2700
free map =0xaa24f0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值