You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用libyaml解析多个YAML文件遇断言错误,该如何解决?

解决libyaml多文件解析的输入源断言问题

libyaml的yaml_parser_t实例一旦绑定了输入源(文件、字符串等),就不允许重复设置——这是因为解析器内部会维护输入相关的状态和资源,重复设置会引发资源冲突,触发你遇到的断言。解决这个问题最可靠的方式是为每个YAML文件创建独立的解析器实例,具体实现如下:

核心思路

为每个配置文件单独完成「初始化解析器→绑定输入源→解析→销毁资源」的流程:

  • 对每个文件,先打开对应的文件句柄
  • 初始化新的解析器实例,将其绑定到当前文件
  • 完成解析后,销毁解析器并关闭文件句柄

代码示例

单个文件解析函数

#include <yaml.h>
#include <stdio.h>
#include <stdlib.h>

int parse_single_yaml(const char *file_path) {
    // 打开配置文件
    FILE *config_file = fopen(file_path, "r");
    if (!config_file) {
        perror("Failed to open config file");
        return -1;
    }

    // 初始化解析器
    yaml_parser_t parser;
    if (!yaml_parser_initialize(&parser)) {
        fprintf(stderr, "Failed to initialize YAML parser for %s\n", file_path);
        fclose(config_file);
        return -1;
    }

    // 将解析器绑定到当前文件
    yaml_parser_set_input_file(&parser, config_file);

    // 解析YAML流(示例:遍历所有事件)
    yaml_event_t event;
    int parse_success = 1;
    do {
        if (!yaml_parser_parse(&parser, &event)) {
            fprintf(stderr, "Parse error in %s: %s (line %zu, column %zu)\n",
                    file_path, parser.problem, parser.problem_mark.line, parser.problem_mark.column);
            parse_success = 0;
            break;
        }

        // 这里添加你的业务逻辑,比如读取配置项
        // 示例:打印事件类型
        // printf("Event type: %d\n", event.type);

        yaml_event_delete(&event);
    } while (event.type != YAML_STREAM_END_EVENT);

    // 强制清理剩余事件(避免泄漏)
    yaml_event_delete(&event);
    // 销毁解析器、关闭文件
    yaml_parser_delete(&parser);
    fclose(config_file);

    return parse_success ? 0 : -1;
}

多文件解析调用

int main() {
    // 示例配置文件列表
    const char *config_files[] = {"global.yaml", "module1.yaml", "module2.yaml"};
    size_t file_count = sizeof(config_files) / sizeof(config_files[0]);

    for (size_t i = 0; i < file_count; i++) {
        printf("Parsing %s...\n", config_files[i]);
        int result = parse_single_yaml(config_files[i]);
        if (result != 0) {
            fprintf(stderr, "Failed to parse %s, continuing with next file\n", config_files[i]);
        }
    }

    return 0;
}

关键注意事项

  • 资源清理:每个解析器使用完毕后必须调用yaml_parser_delete,否则会造成内存泄漏;文件句柄必须关闭,避免资源泄漏。
  • 错误处理:解析过程中若出现错误,要确保所有已初始化的资源(事件、解析器、文件)都被正确清理,避免资源泄漏。
  • 逻辑复用:可以将配置项的读取逻辑封装为独立函数,在parse_single_yaml中调用,实现代码复用。

内容的提问来源于stack exchange,提问作者Newbyte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:52:03