C语言中的键值对

C语言中的键值对,c,struct,C,Struct,我是C编程新手,我正在尝试创建一个键值结构,就像Perl编程一样。我看到了一个解决方案,如: struct key_value { int key; char* value; }; struct key_value kv; kv.key = 1; kv.value = "foo"; 但我不知道如何从这个结构中访问这些值。有人能了解这一点吗?您的代码已经有了访问这些值的方法 kv.key = 1 kv.value = "foo" 获取指定的值很简单 kv.key kv.val

我是C编程新手,我正在尝试创建一个键值结构,就像Perl编程一样。我看到了一个解决方案,如:

struct key_value
{
   int key;
   char* value;
};

struct key_value kv;

kv.key = 1;
kv.value = "foo";

但我不知道如何从这个结构中访问这些值。有人能了解这一点吗?

您的代码已经有了访问这些值的方法

kv.key = 1 
kv.value = "foo"
获取指定的值很简单

kv.key
kv.value
它是一个简单的结构,如果你想要像python dict这样的东西,你需要实现一个更复杂的哈希结构

typedef struct key_value
{
   int key;
   char* value;
}List;

struct key_value k1;
struct key_value k2;
struct key_value k3;

k1.key = 1;
k1.value = "foo";
k2.key = 2;
k2.value = "sec";
k3.key = 3;
k3.value = "third";
您将需要创建N次结构,并按照第一次创建的方式为它们赋值。或者使用N个结构创建数组,并使用循环对其进行迭代赋值

数组:

List arr[29];

int i;
for(i = 0;i<=28;i++){
    arr[i].key = i;
    arr[i].value = "W/e it needs to be";
}
列表arr[29];
int i;

对于(i=0;i“我必须存储30个键/值对”。创建结构数组(键/值)

您可以通过循环将值指定给键和值。 访问
kv
中的任何内容都很简单

`int i = kv[0].key`;// copy value of k[0].key to i

char *v = kv[0].value; // copy value of k[0].value to v;
以下是一个例子:

#include <stdio.h>
#include <stdlib.h>
struct key_value
{
    int key;
    char* value;
};

int main(void)
{
    int number_of_keys = 2;
    struct key_value *kv = malloc(sizeof(struct key_value) * number_of_keys);
    if (kv == NULL) {
        perror("Malloc");
        exit(EXIT_FAILURE);
    }

    kv[0].key = 8;
    kv[0].value = "Test 8 key!";

    kv[1].key = 6;
    kv[1].value = "Test 6 key!";

    printf("Key = %d\nKey value = %s\n", kv[0].key, kv[0].value);
    printf("Key = %d\nKey value = %s\n", kv[1].key, kv[1].value);


    free(kv);
    return 0;
}
#包括
#包括
结构键值
{
int键;
字符*值;
};
内部主(空)
{
_键的整数_=2;
结构键值*kv=malloc(sizeof(结构键值)*键数);
如果(kv==NULL){
佩罗尔(“马洛克”);
退出(退出失败);
}
kv[0],键=8;
kv[0]。value=“测试8键!”;
kv[1],键=6;
kv[1]。value=“测试6键!”;
printf(“键=%d\n键值=%s\n”,千伏[0]。键,千伏[0]。值);
printf(“键=%d\n键值=%s\n”,千伏[1]。键,千伏[1]。值);
免费(千伏);
返回0;
}

您正在寻找的功能需要您自己用C语言实现;例如,结构类型的数组。
下面是一个示例,说明如何读取键的值,而不知道该键将在哪个数组索引处找到。
为了说明这一点,我把钥匙向后编号

请注意,对于不存在密钥等特殊情况,需要更复杂的API定义;我只是盲目地返回最后一个条目,以保持这里的简单性

#include <stdio.h>

#define MAPSIZE 30

struct key_value
{
   int key;
   char* value;
};

struct key_value kvmap[MAPSIZE];

void initmap(void)
{
    int i;
    for(i=0; i<MAPSIZE; i++)
    {
         kvmap[i].key=MAPSIZE-i-1;
         kvmap[i].value="unset";
    }

    kvmap[0].value="zero";
    kvmap[1].value="one";
    kvmap[2].value="two";
    kvmap[3].value="three";
    kvmap[4].value="four";
    kvmap[5].value="five";
    kvmap[6].value="six";
    kvmap[7].value="seven";
    kvmap[8].value="eight";
    kvmap[24].value="find this"; // it has the key "5"

}

char* readmap(int key)
{
    int i=0;
    while ((i<MAPSIZE-1) && (kvmap[i].key!=key))
    {   printf("Not in %d\n", i);
        ++i;}

    // will return last entry if key is not present
    return kvmap[i].value;
}

int main(void)
{
    initmap();

    printf("%s\n", readmap(5));
    return 0;
}
#包括
#定义地图大小30
结构键值
{
int键;
字符*值;
};
结构键_值kvmap[MAPSIZE];
void initmap(void)
{
int i;

对于(i=0;i您缺少的是一个集合。大多数语言都有一种称为字典、映射或关联数组或其变体的数据类型。C没有这种类型的数据结构;事实上,您在C中内置的唯一集合类型是数组。因此,如果您需要某种可以提供键并获取值的数据类型,你必须自己滚动或在互联网上找到一个。后者可能更可取,因为如果你滚动自己的数据结构(特别是如果你是初学者),你很可能会犯错误并产生缓慢的数据结构

为了让您了解最终的结果,这里有一个简单的示例:

您需要一些东西来表示集合;现在称之为
ListMap

struct ListMap;
上述类型称为不完整类型。目前,我们不关心其中包含的内容。除了向周围的实例传递指针外,您无法对其执行任何操作

您需要一个函数将项目插入到集合中。其原型如下所示:

bool listMapInsert(struct ListMap* collection, int key, const char* value);
// Returns true if insert is successful, false if the map is full in some way.
您需要一个函数来检索任意一个键的值

const char* listMapValueForKey(struct ListMap* collection, int key);
您还需要一个函数来初始化集合:

struct ListMap* newListMap();
把它扔掉:

void freeListMap(struct ListMap* listMap);
难点在于如何实现这些函数的功能。无论如何,下面是如何使用它们:

struct ListMap* myMap = newListMap();
listMapInsert(myMap, 1, "foo");
listMapInsert(myMap, 1729, "taxi");
listMapInsert(myMap, 28, "perfect");

char* value = listMapValueForKey(myMap, 28); // perfect
freeListMap(myMap);

这是一个简单的实现。这只是为了举例说明,因为我还没有测试它,搜索条目会随着条目数的增加而线性增加(您可以比使用哈希表和其他结构做得更好)

enum
{
listMapCapacity=20
};
结构列表映射
{
结构键\值kvPairs[listMapCapacity];
大小/数量;
};
结构ListMap*newListMap()
{
struct ListMap*ret=calloc(1,sizeof*ret);
ret->count=0;//由于calloc,严格来说不需要
返回ret;
}
bool listMapInsert(struct ListMap*集合,int键,const char*值)
{
如果(收集->计数==listMapCapacity)
{
返回false;
}
集合->kvPairs[计数]。键=键;
集合->kvPairs[count].value=strdup(值);
计数++;
返回true;
}
常量字符*listMapValueForKey(结构ListMap*集合,int键)
{
const char*ret=NULL;
对于(大小i=0;icount&&ret==NULL;++i)
{
如果(集合->kvPairs[i]。键==键)
{
ret=kvPairs[i]。值;
}
}
返回ret;
}
void freeListMap(struct ListMap*ListMap)
{
if(listMap==NULL)
{
返回;
}
对于(大小i=0;icount;++i)
{
自由(列表映射->kvPair[i].值);
}
免费(列表地图);
}

struct key\u value kv;
之后,
kv.key
kv.value
将是左值。不清楚您在这里要问什么-您知道C中的结构是如何工作的吗?我必须存储30个键/值对。访问该结构的逻辑是什么?您可以将它们放入数组[30]然后用一个键值搜索具有匹配键值的结构并读/写它的值。@Yunnosch你能为此共享一个代码段吗?是的,使用数组要比创建任意数量的单独的
struct
好得多,它们除了名称之外没有任何关系,这对编译器来说并不重要我举一个更好的例子。是的,我同意刚才添加的。我想他会从理解他可以创建多个结构中获得价值。他形成问题的方式我非常怀疑他是否知道什么是结构。
struct ListMap* myMap = newListMap();
listMapInsert(myMap, 1, "foo");
listMapInsert(myMap, 1729, "taxi");
listMapInsert(myMap, 28, "perfect");

char* value = listMapValueForKey(myMap, 28); // perfect
freeListMap(myMap);
enum
{
    listMapCapacity = 20
};
struct ListMap
{
    struct key_value kvPairs[listMapCapacity];
    size_t count;
};

struct ListMap* newListMap()
{
    struct ListMap* ret = calloc(1, sizeof *ret);
    ret->count = 0; // not strictly necessary because of calloc
    return ret;
}

bool listMapInsert(struct ListMap* collection, int key, const char* value)
{
    if (collection->count == listMapCapacity)
    {
        return false;
    }
    collection->kvPairs[count].key = key;
    collection->kvPairs[count].value = strdup(value);
    count++;
    return true;
}

const char* listMapValueForKey(struct ListMap* collection, int key)
{
    const char* ret = NULL;
    for (size_t i = 0 ; i < collection->count && ret == NULL ; ++i)
    {
        if (collection->kvPairs[i].key == key)
        {
            ret = kvPairs[i].value;
        }
    }
    return ret;
}

void freeListMap(struct ListMap* listMap)
{
    if (listMap == NULL)
    {
        return;
    }
    for (size_t i = 0 ; i < listMap->count ; ++i)
    {
        free(listMap->kvPair[i].value);
    }
    free(listMap);
}