我很好奇如何编写C代码来读取输入文件,以灵活的方式。
作为一个非常简单的例子,假设我有变量abcd。我可以写一个输入文件如下

 a = 1.0
 b = 5.0
 c = 2.33
 d = 0.9

而且,如果我声明abcddouble类型,我可以简单地使用
 FILE *fr;
 // set some default values
 double a = 1.0, b = 1.0,
       c = 2.0, d = 2.0;

 fr = fopen("input_file.txt", "rt");

 fscanf(fr, "a = %lf b =  %lf c =  %lf d =  %lf", &a, &b, &c, &d);

 printf("%f %f %f %f\n",
        a, b, c, d);

读取数据。但这看起来很僵硬,例如输入文件中的abcd必须完全按照这个顺序排列,因此使输入文件
 a = 1.0
 c = 5.0
 b = 2.33
 d = 0.9

不起作用,我不能添加评论
 a = 1.0   // This is parameter foo, must have properties P1, P2 and P3
 c = 5.0
 b = 2.33
 d = 0.9

当我有20个变量,而不仅仅是abcd时,这一点尤其重要。任何帮助使这个尽可能灵活是很好的。我在FORTRAN中使用了实现“NAMELLIST”的代码,这真的是一个很好的灵活性,C语言中的代码会很棒。

最佳答案

在评论上转移和扩展。
你可能需要这样的结构:

struct VarMap
{
    const char *name;
    double     *data;
} var_map[] =
{
    { "a", &a }, { "b", &b },
    { "c", &c }, { "d", &d },
};

将(运行时)名称映射到不同的变量。然后使用格式中的"%s = %lf"读取名称(%s允许多字符名称)和值,然后搜索varmap以查找数据的存放位置。
enum { NUM_VARS = sizeof(varmap) / sizeof(varmap[0]) };

char name[10];
double value;

if (fscanf(fr, "%9s = %lf", name, &value) == 2)
{
    int i;
    for (i = 0; i < NUM_VARS; i++)
    {
        if (strcmp(name, varmap[i].name) == 0)
        {
            *varmap[i].data = value;
            break;
        }
    }
    if (i == NUM_VARS)
    {
        fprintf(stderr, "Failed to find match for '%s = %g'\n", name, value);
        ...other error handling?...
    }
}

很明显,如果你有大量的变量,你会想用二进制搜索,甚至是基于散列的名称搜索,你会把搜索抽象成一个函数,而不是像上面的代码那样写在内联。
varmap的初始值设定项提供了一个限制-在大多数情况下,指向的名称和变量在编译时是固定的。另一种机制将使用命名变量数组:
struct NamedVar
{
    const char *name;
    double      value;
};

您可以在结构中使用固定大小的char数组,或者将名称命名为灵活数组成员。
struct NamedVar
{
    double value;
    char   name[];
};

然后,您可以动态分配struct NamedVar值,在数组中保留指向这些值的指针,根据需要添加新的命名变量。
您需要一个函数double named_variable(const char *name)来获取值,而void set_named_variable(const char *name, double value)来设置值。哪种方法最好取决于谁可以设计变量名,以及需要处理多少变量名。对于4个变量或40个变量,struct VarMap方法是合理的;对于400个变量或4000个变量,struct NamedVar方法可能更好。

关于c - 如何为C构造良好/灵活的输入文件以读取数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23829765/

10-12 05:29