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");
}
4
  • 2
    try const int MAX=400; Commented Nov 11, 2013 at 5: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. Commented Nov 11, 2013 at 5: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. Commented Nov 11, 2013 at 6: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++ Commented Nov 11, 2013 at 6:09

6 Answers 6

5

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()).

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

2 Comments

Thanks for the input. It is an assignment where we have to use arrays.
@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.
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;
}

Comments

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];

2 Comments

The const int max=400 runs the program.
The output is wrong. It displays the level and the scores but it displays about a million stars afterwards. When the stars should match the score.
2

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

const int MAX=400;

2 Comments

When i change it to a cosnt variable; the program runs but the output is wrong.
It displays the level and the score correctly but it displays a million stars afterwards.
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)

Comments

0

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

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.