1

I want to initialize an array based on how many lines there are in a text file, so that I can read the text data into the program, but I am having issues with the struct. I so far understand that I need to define the array bounds with a constant, which I've tried to do, but I get errors saying that I am not defining with an integral constant-expression, though I believe that is what I am doing.

I am using g++ to compile my code with the C++17 standard. Below I included only relevant code.

//tools.h

int findMaxID()
{
    std::ifstream fin("\data\items.txt");
    char ch;
    int z = 1;
    while(fin)
    {
        fin.get(ch);
        if(ch == '\n')
            z++;
    }
    return z;
}
const int MaxID = findMaxID();

// data.h

#include"tools.h"

struct ItemData
{
    public:
        unsigned int ID[::MaxID];
        char Name[::MaxID][32];
        char Type[::MaxID][8]; 
};
data.h:15:21: error: size of array 'ID' is not an integral constant-expression
   15 |   unsigned int ID[::MaxID];
      |                   ~~^~~~~
data.h:16:15: error: size of array 'Name' is not an integral constant-expression
   16 |   char Name[::MaxID][32];
      |             ~~^~~~~
data.h:17:15: error: size of array 'Type' is not an integral constant-expression
   17 |   char Type[::MaxID][8];

I'm stumped as to what to do. I've tried absolutely everything, I tried using vector instead of arrays, but I found it awkward and confusing when using it multi-dimensional, and I tried using a pointer to the value. Maybe I set it up wrong. All I know is that I've tried my absolute best to overcome this, but the problem doesn't seem to be in my reach to solve. I hope you can help me with this issue.

  • 1
    That can't be determined at compile time, so it's not able to be used in an array like that. In C++ use `std::vector` for arrays and `std::string` instead of character arrays. – tadman Sep 22 '20 at 05:03
  • What's "awkward and confusing" about them? They're identical to C arrays in usage if sized properly in advance, or if being extended then you'll need to `push_back` or `emplace_back` as necessary. – tadman Sep 22 '20 at 05:03
  • See [this](https://stackoverflow.com/a/34696833) very applicable answer. *[tl;dr]* The array size must be a *compile-time* constant. – dxiv Sep 22 '20 at 05:06
  • The diagnostics from your compiler are fairly self-explanatory. Array dimensions in C++ must be constant expressions (which are evaluated at compile time). `const int MaxID = findMaxID();` does not cause `findMaxID()` to be called and evaluated at compile time. It simply prevents `MaxID` being changed after it is initialised. To use `MaxID` as an array dimension, it is necessary to initialise it with a constant expression that can be evaluated at compile-time (e.g. `const int MaxID = 10`). – Peter Sep 22 '20 at 05:14
  • Does this answer your question? [How to initialize a constant int to use for array size?](https://stackoverflow.com/questions/31226528/how-to-initialize-a-constant-int-to-use-for-array-size) – JaMiT Sep 22 '20 at 05:28

2 Answers2

1

When designing data structures try and think of the single case first:

struct ItemData
{
    public:
        unsigned int ID;
        std::string Name;
        std::string Type; 
};

Then treat these structures in aggregate separately:

std::vector<ItemData> items;

Where you can add entries to that quite easily with emplace_back by reading the data in and parsing it.

tadman
  • 208,517
  • 23
  • 234
  • 262
1

The array size must be a compile-time constant.

In this case your size variable takes the value at runtime and this is forbidden by the standard.

To resolve this problem try to use c++ utilities like std::string for an array of char, and std::vector for an array of other types.

Zig Razor
  • 3,381
  • 2
  • 15
  • 35