如何在 C 中修改现有的 YAML 节点?

Posted

技术标签:

【中文标题】如何在 C 中修改现有的 YAML 节点?【英文标题】:How to modify an existing YAML node in C? 【发布时间】:2017-01-04 11:46:12 【问题描述】:

我不是 C 程序员,但最近对它产生了兴趣。我正在尝试使用 C libyaml 库修改 YAML 文件的节点。当我尝试从事件标量数据修改节点时,编译器不会抱怨,但会出现分段错误错误。

while (!done)

    /* Get the next token. */

    if (!yaml_parser_parse(&parser, &event))
        goto parser_error;

    //yaml_parser_scan(&parser, &token);

    /* Check if this is the stream end. */

    if(beginServerNodes && event.type == 8) 
      beginServerNodes = 0;
    

    if (event.type == YAML_SCALAR_EVENT) 
      if(beginServerNodes == 1) 
        //I WANT TO MODIFY THIS VALUE
        printf("%s\n", event.data.scalar.value);
      
      if(strcmp("servers",event.data.scalar.value) == 0) 
        beginServerNodes = 1;
      
    

    if (event.type == YAML_STREAM_END_EVENT) 
        done = 1;
    
    /* Emit the token. */

    if (!yaml_emitter_emit(&emitter, &event))
        goto emitter_error;

所以当我尝试修改以下值时,在那个循环中

event.data.scalar.value

它的类型必须是yaml_char_t

  yaml_char_t *newHost = "10.132.16.48:6379:1 redis-001";
  event.data.scalar.value = newHost;
  event.data.scalar.length = sizeof(newHost);

编译器不会抱怨,并且运行的代码会因分段错误而死掉。如果在 libyaml 测试目录中看到了示例,但就简单地编辑节点而言,没有什么是直观的,至少对于像我这样的 C 新手来说不是。

【问题讨论】:

好的,我可以在不考虑实际问题的情况下发表评论:大多数程序员不赞成使用goto,当然这不是您刚开始使用C时应该使用的东西。它有一些ligitimate use cases,但在学习 C 时最好远离它,而不是让它成为你日常设计工作流程的一部分。 goto 并不是很难使用,而是像任何其他流控制语句一样使用它导致一些极难发现的错误,从而消除大部分您的时间和学习的大部分乐趣 C. 阅读 E.Dijkstra 的 this classic。 @RodyOldenhuis 我同意你的观点,goto 结构的使用直接取自库本身的示例。 嗯...好吧,奇怪。好吧,那就警告吧! :) 我猜你需要strdup()newHost的数据,长度是通过strlen()计算的 【参考方案1】:

Libyaml 希望可以通过free() 删除每个标量的值。所以需要用malloc()ed 内存初始化这个值:

const char* newHost = "10.132.16.48:6379:1 redis-001";
event.data.scalar.value = (yaml_char_t*)strdup(newHost);
event.data.scalar.length = strlen(newHost);

【讨论】:

以上是关于如何在 C 中修改现有的 YAML 节点?的主要内容,如果未能解决你的问题,请参考以下文章

在保留注释的同时在 java 中修改 YAML

C++ YAML:如何编辑/写入 .yaml 文件中的节点

如何使用yaml-cpp修改map节点(删除key的值)

如何在现有的 Firebase json 结构下添加子节点?

如何在 bash 中将 json 响应转换为 yaml

从现有的 JAVA Spring API 生成 YAML 文件