动态枚举 libconfig 中的键
Dynamically enumerate keys in libconfig
in libconfig
- 是否可以动态枚举键?
举个例子,在这个 example 来自他们 repo 的配置文件中 - 如果有人在 hours
部分发明了更多天数,代码可以动态枚举它们并打印出来吗?
查看文档,我看到很多代码来获取特定字符串或列出数组,但我找不到枚举配置部分的键的示例。
编辑
收到了一些反对票,所以我想我会再想办法更具体一些。
我想使用 libconfig 来跟踪我的应用程序中的某些状态,在应用程序启动时读取最后已知的状态,并在应用程序退出时再次写出。我的应用程序将内容存储在一棵树中(深度为 2)——因此这可以很好地表示为 libconfig 兼容文件中的关联数组,如下所示。关键是 ID 列表 (1234/4567
) 可以更改。我可以在另一个数组中跟踪它们,但如果我可以在下面的 ids
数组中枚举 'keys' - 那会更整洁。
所以
ids = {
"1234" = [1,2,3]
"4567" = [9,10,11,23]
}
例如(伪代码)
foreach $key(config_get_keys_under(&configroot)){
config_get_String($key)
}
我在头文件中看不到任何明显的内容。
您可以使用 config_setting_get_elem
函数获取组、数组或列表的第 n 个元素,然后(如果它是组)使用 config_setting_name
获取它的名称。但是据我所知,您不能在键名中使用数字。所以考虑以下配置结构:
ids = (
{
key = "1234";
value = [1, 2, 3];
},
{
key = "4567";
value = [9, 10, 11, 23];
}
);
然后您可以使用以下代码轻松枚举 ids
的所有成员以获得您想要的值:
#include <stdio.h>
#include <libconfig.h>
int main(int argc, char **argv) {
struct config_t cfg;
char *file = "config.cfg";
config_init(&cfg);
/* Load the file */
printf("loading [%s]...\n", file);
if (!config_read_file(&cfg, file)) {
printf("failed\n");
return 1;
}
config_setting_t *setting, *member, *array;
setting = config_lookup(&cfg, "ids");
if (setting == NULL) {
printf("no ids\n");
return 2;
}
int n = 0, k, v;
char const *str;
while (1) {
member = config_setting_get_elem(setting, n);
if (member == NULL) {
break;
}
printf("element %d\n", n);
if (config_setting_lookup_string(member, "key", &str)) {
printf(" key = %s\n", str);
}
array = config_setting_get_member(member, "value");
k = 0;
if (array) {
printf(" values = [ ");
while (1) {
if (config_setting_get_elem(array, k) == NULL) {
break;
}
v = config_setting_get_int_elem(array, k);
printf("%s%d", k == 0 ? "" : ", ", v);
++k;
}
printf(" ]\n");
}
++n;
}
printf("done\n");
/* Free the configuration */
config_destroy(&cfg);
return 0;
}
in libconfig
- 是否可以动态枚举键?
举个例子,在这个 example 来自他们 repo 的配置文件中 - 如果有人在 hours
部分发明了更多天数,代码可以动态枚举它们并打印出来吗?
查看文档,我看到很多代码来获取特定字符串或列出数组,但我找不到枚举配置部分的键的示例。
编辑
收到了一些反对票,所以我想我会再想办法更具体一些。
我想使用 libconfig 来跟踪我的应用程序中的某些状态,在应用程序启动时读取最后已知的状态,并在应用程序退出时再次写出。我的应用程序将内容存储在一棵树中(深度为 2)——因此这可以很好地表示为 libconfig 兼容文件中的关联数组,如下所示。关键是 ID 列表 (1234/4567
) 可以更改。我可以在另一个数组中跟踪它们,但如果我可以在下面的 ids
数组中枚举 'keys' - 那会更整洁。
所以
ids = {
"1234" = [1,2,3]
"4567" = [9,10,11,23]
}
例如(伪代码)
foreach $key(config_get_keys_under(&configroot)){
config_get_String($key)
}
我在头文件中看不到任何明显的内容。
您可以使用 config_setting_get_elem
函数获取组、数组或列表的第 n 个元素,然后(如果它是组)使用 config_setting_name
获取它的名称。但是据我所知,您不能在键名中使用数字。所以考虑以下配置结构:
ids = (
{
key = "1234";
value = [1, 2, 3];
},
{
key = "4567";
value = [9, 10, 11, 23];
}
);
然后您可以使用以下代码轻松枚举 ids
的所有成员以获得您想要的值:
#include <stdio.h>
#include <libconfig.h>
int main(int argc, char **argv) {
struct config_t cfg;
char *file = "config.cfg";
config_init(&cfg);
/* Load the file */
printf("loading [%s]...\n", file);
if (!config_read_file(&cfg, file)) {
printf("failed\n");
return 1;
}
config_setting_t *setting, *member, *array;
setting = config_lookup(&cfg, "ids");
if (setting == NULL) {
printf("no ids\n");
return 2;
}
int n = 0, k, v;
char const *str;
while (1) {
member = config_setting_get_elem(setting, n);
if (member == NULL) {
break;
}
printf("element %d\n", n);
if (config_setting_lookup_string(member, "key", &str)) {
printf(" key = %s\n", str);
}
array = config_setting_get_member(member, "value");
k = 0;
if (array) {
printf(" values = [ ");
while (1) {
if (config_setting_get_elem(array, k) == NULL) {
break;
}
v = config_setting_get_int_elem(array, k);
printf("%s%d", k == 0 ? "" : ", ", v);
++k;
}
printf(" ]\n");
}
++n;
}
printf("done\n");
/* Free the configuration */
config_destroy(&cfg);
return 0;
}