这是一个包含各种选项的小程序,它们需要一些输入值 - 它们位于struct
中。每个选项都需要struct
的实例,因此array
为struct
。我希望能够在程序退出时保存这些选项并在程序启动时读取它们。但是struct
并不仅仅包含3个变量,并且随着我的小程序的增长,它们可能会及时增长。 struct
的一个例子:
struct S
{
int a;
float b;
std::vector<float> c;
}
保存文件包含与选项一样多的行,每行包含相同的序列,但不同的值由;
分隔,向量的元素用,
和a终止;
,没有空格。对于上面的例子:
13;3.14;0.618,1.618;
7;2.718;12.3,45.6;
...
但是文件可能会损坏,因此读取它会破坏变量并导致程序崩溃。目前,读取数字涉及一个循环(选项/行的数量已知):
float x;
char c;
std::fstream fs;
// file open, flags, etc
fs >> a >> c;
if(c != ';')
{
std::cerr << "Error! ...\n";
break;
}
fs >> b >> c;
if(c != ';')
{
std::cerr << "Error! ...\n";
break;
}
c = ','; // make sure c is not ';'
while(c != ';')
{
fs >> x >> c;
c.push_back(x);
if(c != ',')
{
std::err << "Error...\n";
break;
}
}
而不是break
它可以是abort()
函数,或者是从头开始的函数,而不是问题,但如果有100个变量,我必须为每个人执行此操作。这就是为什么我想要循环它们的原因。显然没有&#34;反思&#34;在C ++中,但它可以通过一些宏来完成。目前,我不了解其中任何一个,所以我尝试了自己的解决方案。首先,我尝试使用模板创建一般use()
函数,但在使用template argument deduction/substitution failed
调用时失败。我尝试auto
作为类型,但也失败了。我认为这是有道理的。那么我想为什么不只是让set/get
处理最坏的类型并在内部转换它。这是成员函数的出现:
enum { INT_A, FLOAT_B, VECTOR_C, ALL };
void set(const int &n, const float &f, const int &i = 0)
{
switch(n)
{
case INT_A: a = static_cast<int>(x); break;
case FLOAT_B: b = x; break;
case VECTOR_C: c[i] = x; break;
}
}
float get(const int &n, const int &i = 0)
{
switch(n)
{
case INT_A: return static_cast<float>(a); break;
case FLOAT_B: return b; break;
case VECTOR_C: return c[i]; break;
}
}
get()
主要用于确认,set()
是我感兴趣的。它似乎工作,我可以设置循环来迭代和自动化过程,但这是一个很好的解决方案(我不知道它是什么,但我不高级)?是否有更好的不涉及外部库?
抱歉延迟,我只是忘了更新它。我决定使用额外的std::vector<float>
将所有变量保存为float
。顺序是原始std::vector<float>
(上例中的c
)在向量中依次排在最后。缺点是它占用了大约两倍的内存,但代码更少。现在,我知道向量c
(以及实际案例中的其余部分)具有最小长度,因此我有两个选项:
如果附加向量包含这些最小长度,则强加长度,然后,当它写入时,我需要if()
决定是否需要写直到最小长度,或高于它,如下所示:
if(c.size()&lt; minLength) //循环写入c [i] 其他 //循环到c.push_back(...)
或者我可以考虑由单个变量的数量构成的附加向量的长度,例如a
和b
,并考虑vector
的长度( c
)为零,因此,在撰写时,代码将缩减为for()
或while()
push_back()
循环。
我选择了第二个,所以struct
现在看起来像这样:
struct S
{
int a;
float b;
std::vector<float> c;
std::vector<float> additional(2); // holds a and b, c islength zero
}
可以在循环中轻松实现向量的写入。快速展示如下:
int n;
float x;
char c;
while(n < maxSizeOfAdditional)
{
switch(n)
{
case 1: a = static_cast<int>(additional[i]); break;
case 2: b = additional[i]; break;
case 3:
{
while(fs >> x >> c)
// loop for writing c.push_back(x)
}
}
++n;
}
由于程序中的其余代码,我需要原始类型,因此需要static_cast
。它现在有效,并且没有&#34;反射&#34;,我也不需要,我只需要一种方式来循环自动化过程。
尽管如此,我还不知道它是不是正统的&#34;做法。就我而言,它似乎解决了我的问题,但我不知道如何考虑这样的事情。更好的是,我不知道&#34;通常&#34;方法是需要读取/写入变量以保存文件的程序,必须驻留在某处的变量(我只是想象它们在struct
中,这就是全部)。我想时间会告诉你。