我是C编程新手,我正在尝试创建Perl Programming中的键值结构。我看到了一个解决方案,如: -
struct key_value
{
int key;
char* value;
};
struct key_value kv;
kv.key = 1;
kv.value = "foo";
但我不知道如何从这个结构中访问这些值。有人可以对此有所启发吗?
答案 0 :(得分:2)
以下是一个例子:
#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;
}
答案 1 :(得分:2)
你缺少的是一个集合。大多数语言具有称为字典或地图或关联数组的数据类型或其一些变体。 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
};
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);
}
答案 2 :(得分:1)
“我必须存储30个键/值对”。创建struct(key_value)数组。
struct key_value
{
int key;
char* value;
};
struct key_value kv[30];
kv[0].key = 1;
kv[0].value = "foo";
printf("%s", kv[0].value);
您可以循环为键和值分配值。
访问kv
中的任何内容都是simple.eg;
`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;
答案 3 :(得分:1)
您正在寻找的功能需要您自己在C中实现;例如一个struct-type数组
下面是一个如何读取键的值的示例,而不知道将在哪个数组索引处找到键。
为了说明这一点,我有向后编号的键。
请注意,特殊情况(如不存在的密钥)需要更复杂的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;
}
答案 4 :(得分:0)
您的代码已经拥有了获取值的方法。
kv.key = 1
kv.value = "foo"
获取分配的值很简单
kv.key
kv.value
这是一个简单的结构,如果你想要类似python dict的东西,你需要实现一个更复杂的哈希结构。