我很好奇如何编写C代码来读取输入文件,以灵活的方式。
作为一个非常简单的例子,假设我有变量a
、b
、c
和d
。我可以写一个输入文件如下
a = 1.0
b = 5.0
c = 2.33
d = 0.9
而且,如果我声明
a
、b
、c
和d
是double
类型,我可以简单地使用 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);
读取数据。但这看起来很僵硬,例如输入文件中的
a
、b
、c
和d
必须完全按照这个顺序排列,因此使输入文件 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个变量,而不仅仅是
a
、b
、c
和d
时,这一点尤其重要。任何帮助使这个尽可能灵活是很好的。我在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/