循环结构

时间:2018-04-15 12:07:50

标签: c++ loops struct

这是一个包含各种选项的小程序,它们需要一些输入值 - 它们位于struct中。每个选项都需要struct的实例,因此arraystruct。我希望能够在程序退出时保存这些选项并在程序启动时读取它们。但是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(以及实际案例中的其余部分)具有最小长度,因此我有两个选项:

  1. 如果附加向量包含这些最小长度,则强加长度,然后,当它写入时,我需要if()决定是否需要写直到最小长度,或高于它,如下所示:

    if(c.size()&lt; minLength)     //循环写入c [i] 其他     //循环到c.push_back(...)

  2. 或者我可以考虑由单个变量的数量构成的附加向量的长度,例如ab,并考虑vector的长度( c)为零,因此,在撰写时,代码将缩减为for()while() push_back()循环。

  3. 我选择了第二个,所以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中,这就是全部)。我想时间会告诉你。

0 个答案:

没有答案
相关问题