【问题标题】:How to easily parse an array from an INI file to an array in C?如何轻松地将数组从 INI 文件解析为 C 中的数组?
【发布时间】:2021-01-01 22:37:08
【问题描述】:

在我的代码中,我使用 iniparser (https://github.com/ndevilla/iniparser) 来解析 double、int 和字符串。但是,我对解析数组很感兴趣,用逗号分隔,例如

arr = val1, val2, ..., valn

有什么简单快捷的方法,比如上面的解析器?

【问题讨论】:

  • 只需将它们解析为 double、int、strings 等并将它们添加到数组中。
  • C 并没有真正的通用数组,因此您需要发明自己的结构来以有意义的形式表示这些。
  • @tadman 他不是在问将不同类型放在同一个数组中。
  • @Fredrik -- OP 可能 询问将不同类型放在同一个数组中。目前尚不清楚(至少对我而言)val1 等是什么类型。它们可能是同一类型,也可能不是。无论如何,可能有必要创建某种数据结构来表示可变长度数组,无论它包含什么类型,因为 C 并没有对此提供任何内置支持。
  • @Fredrik 这与类型无关,而是在 C 数组中没有整数大小组件。如果没有自定义结构,就无法在 C 中说“任意数量的 int 值”。

标签: c parsing ini


【解决方案1】:

最好的方法是制作自己的结构。 您可以在可以为代码导入的 Web 结构上轻松找到它们。另一个不太好的解决方案是将您的值作为 void 指针。当您想取回您的值时,您可以取回 void 指针并将其转换为您想要的值(int、double、char ect)。但这可能会与价值观相冲突,因此您必须小心。您必须知道指针的哪个单元格中的类型值。这不是理想的方式,但它是一种避免自己制作结构的作弊方式。

【讨论】:

  • 他不是在问将不同类型放在同一个数组中。
  • 虽然它缺乏一些细节,但这大体上是正确的答案。如果您想在 C 中为复杂的数据结构建模(并且它不必非常复杂),您可以编写或获取一些代码来执行此操作。 OP 已经找到了一些可以处理基本解析的东西,但是对于新工作来说还不够聪明。所以选择归结为(1)扩展它,(2)写一个新的,或者(3)找到一个更好的。
【解决方案2】:

你可以使用libconfini,它支持数组。

test.conf:

arr = val1, val2, ..., valn

test.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <confini.h>

struct my_conf_T {
    size_t arrlen;
    char ** arr;
};

static int my_listnr (IniDispatch * this, void * v_conf) {
    #define conf ((struct my_conf_T *) v_conf)
    if (ini_string_match_si("arr", this->data, this->format)) {
        conf->arrlen = ini_array_get_length(this->value, INI_COMMA, this->format);
        if (!conf->arrlen || !this->v_len) {
            /*  Array is empty  */
            return 0;
        }
        conf->arr = (char **) malloc(conf->arrlen * sizeof(char *) + this->v_len + 1);
        if (!conf->arr) {
            fprintf(stderr, "malloc() failed\n");
            exit(1);
        }
        char * remnant = (char *) ((char **) conf->arr + conf->arrlen);
        memcpy(remnant, this->value, this->v_len + 1);
        for (size_t idx = 0; idx < conf->arrlen; idx++) {
            conf->arr[idx] = ini_array_release(&remnant, INI_COMMA, this->format);
            ini_string_parse(conf->arr[idx], this->format);
        }
    }
    return 0;
    #undef conf
}

int main () {
    struct my_conf_T my_conf = (struct my_conf_T) { 0 };
    if (load_ini_path("test.conf", INI_DEFAULT_FORMAT, NULL, my_listnr, &my_conf)) {
        fprintf(stderr, "Sorry, something went wrong :-(\n");
        return 1;
    }
    if (my_conf.arr) {
        /*  Do something with `my_conf.arr`...  */
        for (size_t idx = 0; idx < my_conf.arrlen; idx++) {
            printf("arr[%zu] = %s\n", idx, my_conf.arr[idx]);
        }
        free(my_conf.arr);
    }
    return 0;
}

输出:

arr[0] = val1
arr[1] = val2
arr[2] = ...
arr[3] = valn

附:我恰好是作者。

【讨论】:

    猜你喜欢
    • 2021-09-18
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多