C语言中的键值对
我是C编程新手,我正在尝试创建一个键值结构,就像Perl编程一样。我看到了一个解决方案,如: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
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);
}