1

I keep getting an error that says ISO C++ forbids variable-size array.

I am suppose to have an output that displays

Level       Score          Stars
----------------------------------
1              3840           ***

and so on....

Here is my program

#include <iostream> // access to cin, cout
#include <cstring>
#include <cstdlib>
#include<fstream>


using namespace std;

int buildArrays(int A [], int B [], int C [])
{
    int i = 0, num;
    ifstream inFile;
    inFile.open("candycrush.txt");

    if (inFile.fail())
    {
        cout << "The candycrush.txt input file did not open" << endl;
        exit(-1);
    }
    while (inFile)
    {
        inFile >> num;
        A[i] = num;

        inFile >> num;
        B[i] = num;

        inFile >> num;
        C[i] = num;

        i++;
    }
    inFile.close();

    return i;
}
void printArrays(string reportTitle, int levelsArray [], int scoresArray [], int starsArray [], int numberOfLevels)
{
    cout << endl;
    cout << reportTitle << endl;
    cout << "Levels\tScores\tStars" << endl;
    cout << "---------------------" << endl;

    for (int i = 0; i < numberOfLevels; i++)
    {
        cout << levelsArray[i] << "\t" << scoresArray[i] << "\t";
        for (int j = 0; j < starsArray[i]; j++)
        {
            cout << "*";
        }
        cout << endl;
    }
}

void sortArrays(int levelsArray [], int scoresArray [], int starsArray [], int numberOfLevels)
{
    for (int i = 0; i < numberOfLevels; i++)
    {
        for (int j = 0; j < numberOfLevels; j++)
        {
            if (levelsArray[i] < levelsArray[j])
            {
                int temp1 = levelsArray[i];
                int temp2 = scoresArray[i];
                int temp3 = starsArray[i];

                levelsArray[i] = levelsArray[j];
                scoresArray[i] = scoresArray[j];
                starsArray[i] = starsArray[j];

                levelsArray[j] = temp1;
                scoresArray[j] = temp2;
                starsArray[j] = temp3;
            }
        }
    }
}


int main()
{
    int MAX = 400;         (This is where I am getting my valid array size error)
        int levelsArray[MAX];
    int scoresArray[MAX];
    int starsArray[MAX];

    int numberOfLevels = buildArrays(levelsArray, scoresArray, starsArray);

    printArrays("Candy Crush UNSORTED Report", levelsArray, scoresArray, starsArray, numberOfLevels);
    sortArrays(levelsArray, scoresArray, starsArray, numberOfLevels);
    printArrays("Candy Crush SORTED Report", levelsArray, scoresArray, starsArray, numberOfLevels);

    system("pause");
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Dave Lee
  • 43
  • 1
  • 1
  • 5
  • 2
    try `const int MAX=400;` – billz Nov 11 '13 at 05:41
  • GCC (well, the `g++` compiler in the GNU Compiler Collection, aka GCC) allows VLAs by default, but the C++ standard does not. In standard C++, array bounds must be constants in contexts such as your `main()`. Using a variable `MAX` instead of a `const int MAX` means a VLA, even though it is always the same size (just because the dimension is not a constant `int`). Hence the warning, and hence the recommended fix. – Jonathan Leffler Nov 11 '13 at 05:44
  • If infile has more than 1200 numbers in it, you will get a segfault in buildArrays. I would read up on containers and use a std::vector or a std::list rather than arrays. In the interim, if you use a constant for MAX, I would add: if (i>MAX) break; to your while loop in buildArrays. – Ian Thompson Nov 11 '13 at 06:03
  • Use std::vector rather than arrays (for dynamic arrays C++11 or both static and dynamic sized arrays in C++03). Use std::array for static sized arrays in C++11. There is no reason to use bare arrays in C++ – Martin York Nov 11 '13 at 06:09

6 Answers6

4

Unless you (or your teacher, if you're doing this as homework) are intent on doing this badly, you should not simply convert MAX to a const.

Instead you should use std::vector instead of using arrays at all.

As long as you're at it:

  1. Create a struct to hold the three parts of a single score.
  2. Use std::sort instead of your own sorting function.
  3. Overload operator>> and operator<< to do I/O on score objects.
  4. Prefer one-step initialization over default-construction followed by the real initialization (e.g., creating, then separately opening a stream as well as creating then separately filling the vector).
  5. Don't ever use while (stream) read_data1. Always test the result of reading the data, and react to that result.

Using those, we end up with code something like this:

struct score { 
    int level;
    int score;
    int stars;

    bool operator<(score const &other) const { 
        return level < other.level;
    }

    friend std::istream &operator>>(std::istream &is, score &s) { 
        return is >> s.level >> s.score >> s.stars;
    }

    friend std::ostream &operator<<(std::ostream &os, score const &s) { 
         return os << s.level << "\t" 
                   << s.score << "\t"
                   << std::string(s.stars, '*');
    }
};

int main() { 
    std::ifstream in("candycrush.txt");
    std::vector<score> scores{std::istream_iterator<score>(in),
                              std::istream_iterator<score>()};

    std::cout << "Unsorted:\n";
    for (auto const &s : scores)
        std::cout << s << "\n";

    std::cout << "\n";

    std::sort(scores.begin(), scores.end());
    std::cout << "Sorted:\n";

    for (auto const &s : scores) 
        std::cout << s << "\n";
}

You should probably also add something to deal with two scores with equal levels (e.g., by comparing scores in that case), but that's probably a subject for another answer/diatribe.


1. ...or while (stream.good()) or while (!stream.eof()).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks for the input. It is an assignment where we have to use arrays. – Dave Lee Nov 11 '13 at 06:21
  • 1
    @Dave Lee: The lesson to learn then is that your teacher is about 15 years behind the rest of the world, which is rather painful in IT. – MSalters Nov 11 '13 at 09:08
2

gcc support variable size arrays, but other compilers do not. Try.

int main()
{
    #define MAX 400        /* use macro instead of stack variable */
    int levelsArray[MAX];
    int scoresArray[MAX];
    int starsArray[MAX];
    /* rest of your code */
    return 0;
}
2

The array size should be a compile time constant in C++ for most compilers. Try

#define MAX 400;
...
int levelsArray[MAX];

or

const int MAX=400;
...
int levelArray[MAX];
jester
  • 3,491
  • 19
  • 30
2

You need to make the MAX variable to const variable. Try this:

const int MAX=400;
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Jiez
  • 35
  • 4
2
#include <iostream> // access to cin, cout
#include <cstring>
#include <cstdlib>
#include<fstream>

#define MAX 400 //<- Try this

using namespace std;

I would also recommend using classes when dealing with multiple arrays. With the use of a class, there will be no need for you to pass multiple arrays to a function and set the parameter of the function with that long list of arrays. Such as this one:

void printArrays(string reportTitle, int levelsArray [], int scoresArray [], int starsArray [], int numberOfLevels)
user2972206
  • 143
  • 1
  • 1
  • 7
0

Follow the vector usage instead (when variable sized array required for your purposes): https://stackoverflow.com/a/49021923/4361073

parasrish
  • 3,864
  • 26
  • 32