I'm new at this and haven't done much, but I'm really stuck on making a compile-time sized array, which is a class object. And maybe there's a way to save all the information from file, while occupying less of memory? Here's a bit of my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Beer
{
public:
string name;
string rating;
string country;
string alc;
string type;
};
int main() //Function uses ''bytes of stack/exceeds analyze:stacksize '16384'.
//Consider moving some data to heap
{
ifstream file("beer.txt");
if (!file.good())
{
cout << "Error. File was not found." << endl;
exit(EXIT_FAILURE);
}
else
{
int count;
string line;
ifstream file("beer.txt");
int count = 0;
for (int i = 0; !file.eof(); i++)
{
getline(file, line);
count++;
}
const int SIZE = count; //<- this is the place i'm struggling with
Beer allBeers[SIZE]; //expression must have a constant value
Beer currentBeer;
for (int i = 0; !file.eof(); i++)
{
getline(file, currentBeer.name, '\t');
getline(file, currentBeer.rating, '\t');
getline(file, currentBeer.country, '\t');
getline(file, currentBeer.alc, '\t');
getline(file, currentBeer.type, '\n');
allBeers[i] = currentBeer;
}
}
file.close();
return 0;
}
The main problem with your code is in the following two lines:
const int SIZE = count; //<- this is the place i'm struggling with
Beer allBeers[SIZE]; //expression must have a constant value
Now, although SIZE
is defined as const
it is not a compile-time constant! Further, arrays in C++
need dimensions that are compile-time constants. (Your const
qualifier means only that, once initialized, the value of SIZE
cannot be changed.)
The simple, "old-style-C++" way of working around this is to declare allBeers
as a pointer and use the new
operator to create the 'array buffer' at run-time (when the actual value of SIZE
is known):
const int SIZE = count; // Don't really need this, now - could just use "count"
Beer* allBeers = new Beer[SIZE]; // You can still use allBeers[i] to access!
But, here, you shoud be sure to execute delete[] allBeers;
when you're done with the array/buffer.
A more modern approach would be to use the std::vector
type, in which case freeing memory takes care of itself when the object goes out of scope:
const size_t SIZE = size_t(count);
std::vector<Beer> allBeers(SIZE);
Again, you can then access using allBeers[i]
.
Feel free to ask for further clarification and/or explanation.