0

I'm trying to get the numbers of lines of input file to be size of array, but it keeps giving error that expression of the array must be constant. Here is my code:

 int main() {
    int count = 0;
    string line;
    ifstream infile("students.dat");
    while (getline(infile, line))
        count++;
    cout << "Numbers of input is: " << count << endl;
    const int size = count;
    double max, min, average;
    int freshman, sophomore, junior, senior;
    string firstname[size];
    string lastname[size];
    string year[size];
    double grade[size];
    cout << "name\n";
    for (int i = 0; i < size; i++) {
        infile >> firstname[i] >> lastname[i]
            >> year[i] >> grade[i];
    }
    max = FindMax(size, grade);
    cout << "\nHighest grade: " << max;

    min = FindMin(size, grade);
    cout << "\nLowest grade: " << min;

    average = FindAvg(size, grade);
    cout << "\nClass average: " << average;

    FindYear(size, year);
    infile.close();
    return 0;
}

Sample input file:

John Omi freshman 66

Katy Hill sophomore 55

Jeff Ozco freshman 90

Ashley
  • 1
  • 1
  • How are your `Find*` functions implemented? – Chris Nov 09 '21 at 03:21
  • 1
    `string year[size];` this is an array declaration and the `size` must be a constant when compiling example `size =100;`. You can use `std::vector` or dynamic allocation `new` as a solution. [details](https://stackoverflow.com/questions/17259098/how-to-declare-an-array-without-specific-size) – Peter Lee Nov 09 '21 at 03:47
  • Array declarations have to be done with a specific size. So, where ever in this code an array is being declared, the compiler expects to know its size which has to be a constant value. For instance instead of 'string firstname[size];' it should be 'string firstname[10];' . If you really need a container which can keep on expanding as elements are filled into it dynamically then better go with something like std::vector. – dorKKnight Nov 09 '21 at 03:52

2 Answers2

0

constant means compile-time constant, which means the compiler would know its exact value at compile time. For example:

10 // constant

#define VAL 10
VAL // constant

const int val = 10 + 1;
val // constant

The size in your code is a variable that its value is not known until the program runs and reads your file, counts its line. It is called a run-time variable.

ABacker
  • 190
  • 4
0

This here is wrong:

size_t size = count; // obtain the number of elements
string firstname[size]; //< Fails with a compiler error

The declaration something[<size>] tells the compiler to generate space for <size> elements something. Since you know the number of elements (count) only at runtime, the compiler does not know what to do. The size parameter must be a (fixed) number, when the compiler translates your source into binary code.

That said: Please learn the std library. std is part of the C++ language!

Don't ever use [] for vectors/arrays anymore (unless in very specific instances).

The std library has a whole lot of containers that are very easy to use. The most prominent container is std::vector.

Rewrite your code, for example like this:

std::vector<std::string> firstname;
firstname.resize(count);
for (...)
   infile >> firstname.at(i);

Or better still:

struct student
{
   std::string firstname;
   std::string lastname;
   ...
};
...
std::vector<student> students;
while (!infile.eof()) {
   std::string first, last, this, that;
   infile >> first >> last >> this >> that;
   students.emplace_back(first, last, this, that);
// or alternatively
   students.push_back(student(first, last, this, that));

Like I said: The std library is part of the C++ standard.

Hajo Kirchhoff
  • 1,969
  • 8
  • 17
  • I like most of what you wrote, but see [Why !.eof() inside a loop condition is always wrong.](https://stackoverflow.com/q/5605125/9254539) – David C. Rankin Nov 09 '21 at 09:03