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.

5
  • 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. Commented Sep 22, 2020 at 5: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. Commented Sep 22, 2020 at 5:03
  • See this very applicable answer. [tl;dr] The array size must be a compile-time constant. Commented Sep 22, 2020 at 5: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). Commented Sep 22, 2020 at 5:14
  • Does this answer your question? How to initialize a constant int to use for array size? Commented Sep 22, 2020 at 5:28

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.