如何使用最少的代码行将C结构存储在人类可读的文件中?

时间:2013-06-24 17:44:12

标签: c linux configuration-files

我有一个科学仪器的守护进程,需要保留大约100个唯一变量。目前,这些设置以二进制形式存储在显式地址中,并且每个设置都使用唯一的getter和setter进行访问。这完全不可维护。我想在合理的结构中将设置组合在一起,并将这些结构保存到文件中。如果文件不完整,我也会有默认值。什么库或技术允许我用尽可能少的代码行保存和恢复这些结构?

3 个答案:

答案 0 :(得分:2)

如果您想要人类可读的文件,则不能简单地使用库序列化它们。您需要编写一个函数,给定文件名和结构,将在文件中写入结构的内容。我建议您使用一行=一个成员,但也写成员的名称,所以你可以通过这种方式找到失踪的成员:name:value 然后,另一个函数将需要从文件中检索结构。您可以将JSON与jansson库一起使用,而不是编写自己的格式。 **编辑:正如评论所说,libjson是另一种选择,可用于C和C ++。

答案 1 :(得分:1)

“最短”有几个含义

  • 快速处理
  • 尽量少吃内存
  • 简单快捷的代码

我建议使用简单的文本格式来序列化它们,可能是JSON(或者YAML或XML)。这种格式的优点是它们在某种程度上仍然是人类“可读”的(最后是程序员)。

存在许多JSON库(特别是在C和C ++中):C中的jansson,C ++的jsoncpp等等......

您的科学仪器只运行一个小型8位控制器吗?如果是,您可能会受到代码大小的限制......

我还建议记录序列化格式。

答案 2 :(得分:1)

序列化C结构的最快/最简单方法是使用X-macros。这允许您一起定义相关属性并重用元素。此示例不执行任何应该执行的错误检查,但如果实现少于30行,则很难找到较短的错误。可以使用更精细的用法,例如自动创建getter和setter。

#include <stdio.h>

#define SETTINGS_TABLE \
    X(float,  "%f", foo, 2.71818) \
    X(float,  "%f", bar, 0.70711) \
    X(int,    "%i", baz, 42)

#define X(type, fmt, name, default) type name ;
struct Settings { SETTINGS_TABLE };
#undef X

#define X(type, fmt, name, default) default ,
struct Settings settings = { SETTINGS_TABLE };
#undef X

void dump(FILE *f)
{
#define X(type, fmt, name, default) fprintf(f, "%s=" fmt "\n", #name, settings.name);
    SETTINGS_TABLE
#undef X
}

void load(FILE *f)
{
#define X(type, fmt, name, default) fscanf(f, #name "=" fmt, &settings.name);
    SETTINGS_TABLE
#undef X
}

int main(int argc, char *argv[])
{
    FILE *cfg;

    cfg = fopen(argv[1], "r");
    load(cfg);
    fclose(cfg);
    dump(stdout);

    return 0;
}