0

I have an error when compiling my code, with multidimensional array.

C:\Users\Tobi13\Desktop\Projet C++\Code\Test\Test111\map.hpp|17|error: declaration of 'levelchargement' as multidimensional array must have bounds for all dimensions except the first|

And I don't understand at all. I have searched on the internet but I didn't found anything.

The code of map.hpp

class Map{
    public:
        void        ChargementFichiersMap();
        void        ChargementFichierElements();
static  int         widthmap, heightmap;
        int         floorx, floory, floorwidth, floorheight;
        int         wallx, wally, wallwidth, wallheight;
        int         tpx, tpy, tpwidth, tpheight;
        char        *levelchargement[][]= new char [widthmap][heightmap];
        sf::IntRect wallrect, floorrect, tprect;
        sf::Texture tileset;

};

map.cpp

void Map::ChargementFichiersMap()
{
    ifstream fichiermap("map1.txt", ios::in);
    fichiermap >> widthmap >> heightmap;
    fichiermap.ignore();
    char lecture;
    int i=0;
    int j=0;
    while(fichiermap.get(lecture))
    {
        if(lecture==0x0A) // 0x0A est le code hexa pour le saut de ligne
        {
            j++;
            i=0;
            cout << "\n";
        }
        else
        {
            levelchargement[i][j]=lecture;
            i++;
            cout << lecture;
        }
    }
    fichiermap.close();

    ifstream fichiernommap("nom_map.txt", ios::in);
    char nommap;
    fichiernommap >> nommap;
    tileset.loadFromFile(nommap);
    fichiernommap.close();

}

void Map::ChargementFichierElements()
{
    ifstream fichierfloor("floor.txt", ios::in);
    fichierfloor >> floorx >> floory >> floorwidth >> floorheight;
    floorrect(floorx, floory, floorwidth, floorheight);
    fichierfloor.close();

    ifstream fichierwall("wall.txt", ios::in);
    fichierwall >> wallx >> wally >> wallwidth >> wallheight;
    wallrect(wallx, wally, wallwidth, wallheight);
    fichierwall.close();

    ifstream fichiertp("tp.txt", ios::in);
    fichiertp >> tpx >> tpy >> tpwidth >> tpheight;
    tprect(tpx, tpy, tpwidth, tpheight);
    fichiertp.close();
}

main.cpp

int main()
{
    sf::RenderWindow window(sf::VideoMode(720,480), "SFML works?");
    Map test;
    test.ChargementFichiersMap();
    test.ChargementFichierElements();
    while (window.isOpen())
    {
            sf::Vector2f taille(32.f,32.f);
            for (float y = 0; y < test.heightmap; y++)
            {
                for (float x = 0; x < test.widthmap; x++)
                {
                    switch (test.*(levelchargement[int(x)][int(y)]))
                    {
                        case 'W':
                            {
                                sf::RectangleShape wall(taille);
                                wall.setTexture(&test.tileset);
                                wall.setTextureRect(test.wallrect);
                                wall.setPosition(x*32.f, y*32.f);
                                window.draw(wall);
                                break;
                            }

                         case ' ':
                             {
                                sf::RectangleShape floor(taille);
                                floor.setTexture(&test.tileset);
                                floor.setTextureRect(test.floorrect);
                                floor.setPosition(x*32.f, y*32.f);
                                window.draw(floor);
                                break;
                             }

                        case 'T':
                             {
                                sf::RectangleShape tp(taille);
                                tp.setTexture(&test.tileset);
                                tp.setTextureRect(test.tprect);
                                tp.setPosition(x*32.f, y*32.f);
                                window.draw(tp);
                                break;
                             }
                         default:
                            {
                                sf::RectangleShape defaut(taille);
                                defaut.setFillColor(sf::Color::Blue);
                                defaut.setPosition(x*32.f, y*32.f);
                                window.draw(defaut);
                                break;
                            }
                    }
                }
            }
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.display();
    }

    return 0;
}

The whole code is working if put without any class and all, but now I have to do it in a Object Oriented programming way. I hope you'll help me, have a good day !

  • 2
    possible duplicate of [How do I declare a 2d array in C++ using new?](http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new) – Fabio says Reinstate Monica Jun 11 '15 at 23:06
  • `char *levelchargement[][]= new char [widthmap][heightmap];` is illegal; the dimensions of a C-style array must be compile-time constants. I see that you have made `widthmap` and `heightmap` be `static`; can you explain why? You seem to read them in during a non-static member function, so this means that if you have two `Map`s then one of them will end up with `widthmap` and `heightmap` not actually representing your array's dimensions. – M.M Jun 11 '15 at 23:59
  • Hello Matt. I have put them in static because there was an error if I didn't... And I don't intend to have 2 objects Map anyway. – Tobinounet Jun 12 '15 at 00:29
  • Changing the variables to `static` just to fix an error was likely the wrong way to do it. What was the actual error? – Remy Lebeau Jun 12 '15 at 01:00
  • This looks very wrong: `switch (test.*(levelchargement[int(x)][int(y)]))`. It should be `switch (test.levelchargement[int(x)][int(y)])` instead. – Remy Lebeau Jun 12 '15 at 01:04
  • I don't even remember the error... And the test.*(levelchargement) didn't work without the *. – Tobinounet Jun 12 '15 at 07:21
  • `.*` is a special **pointer-to-member-of-object** operator, used for accessing class members indirectly via runtime pointers. But dereferencing `levelchargement` does not yield a pointer-to-member, it yields a single `char`, so `test.*char` is not legal. – Remy Lebeau Jun 12 '15 at 16:36

1 Answers1

0

char *levelchargement[][]= new char [widthmap][heightmap]; is not a valid declaration or allocation for a multi-dimentional array. Since you are dynamically allocating the array at runtime, you need to move the allocation into the class constructor and use this syntax instead:

class Map{
    public:
        Map();
        Map(const Map&);
        ~Map();
        ...
        char        **levelchargement;
        ...
};

Map::Map()
{
    ...
    levelchargement = new char*[widthmap];
    for (int i = 0; i < widthmap; ++i)
        levelchargement[i] = new char[heightmap];
    ...
}

Map::Map(const Map &src)
{
    ...
    levelchargement = new char*[widthmap];
    for (int i = 0; i < widthmap; ++i)
        levelchargement[i] = new char[heightmap];
    ...
}

Map::~Map()
{
    for (int i = 0; i < widthmap; ++i)
        delete[] levelchargement[i];
    delete[] levelchargement;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    `vector` should be used instead of `new` and `delete` to allocate a jagged array – M.M Jun 11 '15 at 23:59
  • Well, now I have a problem on the line floorrect(floorx, floory, floorwidth, floorheight); error: no match for call to '(sf::IntRect {aka sf::Rect}) (int&, int&, int&, int&) How do I access the floorx? – Tobinounet Jun 12 '15 at 00:02
  • The problem is not with `floorx`. `floorrect` is a member variable of type `sf::IntRect` in the `Map` class, and your code is trying to invoke `operator()` on that variable. The compiler is complaining that `sf::IntRect` does not implement that. What are you trying to do exactly with that statement? Update `floorrect` with new values? If so, then see if `sf::IntRect` implements such a method, eg: `floorrect.setValues(floorx, floory, floorwidth, floorheight);`. My guess is that you probably meant to use `floorrect = sf::IntRect(floorx, floory, floorwidth, floorheight);` instead. – Remy Lebeau Jun 12 '15 at 00:29
  • As I said, it worked when everything was in the same file, before trying to put all the code in object oriented programming. To set the values of a rectangle, you have to say the name of it and in () the 4 values. http://www.sfml-dev.org/documentation/2.0-fr/classsf_1_1Rect.php – Tobinounet Jun 12 '15 at 00:42
  • So I tried to put them in the function directly because i don't use them for another use, and it doesn't change anything (Yes I have deleted them from the .hpp) int floorx, floory, floorwidth, floorheight; fichierfloor >> floorx >> floory >> floorwidth >> floorheight; floorrect(floorx, floory, floorwidth, floorheight); – Tobinounet Jun 12 '15 at 00:47
  • @Tobinounet: That documentation you linked to is describing `sf::Rect` **constructors** in regards to `()`. To invoke the constructor in the code you have shown, you need to use `floorrect = sf::IntRect(floorx, floory, floorwidth, floorheight);` – Remy Lebeau Jun 12 '15 at 01:03
  • But I don't understand. Why did it work back when everything was in the same file? Without function or anything? Moreover, in the tutorial, they use what i'm doing so... – Tobinounet Jun 12 '15 at 07:27
  • @Tobinounet: I can't answer that as you have not shown what the original code looked like. But if the code you have shown is anything like the tutorial code, then the tutorial is wrong. – Remy Lebeau Jun 12 '15 at 16:36
  • Well, I tried to adapt it, and that's where i'm doing it wrong. But anyway, thanks guys, it's ok now because my main question is solved. Thanks ! By the way, how do I put the thing solved? – Tobinounet Jun 12 '15 at 16:38
  • See [What should I do when someone answers my question?](http://stackoverflow.com/help/someone-answers) and [What does it mean when an answer is "accepted"?](http://stackoverflow.com/help/accepted-answer) – Remy Lebeau Jun 12 '15 at 16:43