0

So I am somewhat new to programming in classes, and I am unsure what I'm doing wrong with my code, as I am trying to print a 2 dimensional array but an error comes up when trying to build it. Here it is:

#include <iostream>

using namespace std;

class PlaneSeats
{
private:
    char seatAvailability[7][4];

public:
    PlaneSeats();
    void displayAvailability();
};

PlaneSeats::PlaneSeats()
{
    seatAvailability[7][4] = {{'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'}};
}

void PlaneSeats::displayAvailability()
{
    cout << row+1 << " ";
    for (int column = 0; column<4; column++)
    {
        cout << seatAvailability[row][column] << " ";
    }
    cout << endl;
}

int main()
{
    PlaneSeats plane;
    plane.displayAvailability();
    return 0;
}

The errors that come up when building are:

'row' was not declared in this scope    line 27

Symbol 'row' could not be resolved    line 27

Symbol 'row' could not be resolved    line 30

Multiple markers at this line    line 22
    - cannot convert '<brace-enclosed initializer list>' to 'char' in assignment
    - extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by
    default]
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92

5 Answers5

2

I agree with Blake's assessment mostly, but I think OP's intention for displayAvailability is more like this:

void PlaneSeats::displayAvailability()
{
    for (int row = 0; row<7; row++)
    {
        cout << row+1 << " ";
        for (int column = 0; column<4; column++)
        {
            cout << seatAvailability[row][column] << " ";
        }
        cout << endl;
    }
}

with the additional for loop for rows around the printing of the columns.

Next, the OP can't do the static initialization in the contructor, at least not that way, but thanks to the miracle of modern C++ they can do this:

class PlaneSeats
{
private:
    char seatAvailability[7][4] =
    {
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'}
    };
public:
    PlaneSeats();
    void displayAvailability();
};

Note however that the OP declared an array of 7 rows and only assigned values to six of them. This is unlikely to crash because the array entries have been allocated, but ventures into undefined behaviour and no one knows what values will be placed in those uninitialized slots as a result.

Now for the nagging.

Using 7 and 4 as raw numbers is an unnecessary risk. They are much safer as named constant values. Why? Because if all uses reference the same value, you only need to make one code change, to the constant, to change the size of the array. This also protects against the inverse, forgetting to change at least one value. You either try to print outside the bounds of the array and likely crash or print too little of it.

This changes the class definition a bit:

class PlaneSeats
{
private:
    static constexpr int numrows = 7;
    static constexpr int numcols = 4;
    char seatAvailability[numrows][numcols] =
    {
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'},
        {'A', 'B', 'C', 'D'}
    };
public:
    PlaneSeats();
    void displayAvailability();
};

And a similar change to displayAvailability

void PlaneSeats::displayAvailability()
{
    for (int row = 0; row<numrows; row++)
    {
        cout << row+1 << " ";
        for (int column = 0; column<numcols; column++)
        {
            cout << seatAvailability[row][column] << " ";
        }
        cout << endl;
    }
}

This also makes the code read a bit better because 7 is just a number and numrows contains some hints of context.

And of course everybody's favourite nag: Why is "using namespace std" considered bad practice?

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • great answer, I learned something ! So, initialization in the class is possible since C++11 I imagine ? Even for static variables ? – blakelead Oct 01 '15 at 06:15
  • `static const` integers have been OK since C++03, I think. Wasn't writing any C++ back then so I'm not sure, but C++11 loosened a lot of the init restrictions. To the the folks writing compilers and making this all possible, I salute you! – user4581301 Oct 01 '15 at 06:23
  • Thanks heaps for that! Yeah, there is actually a bit more of the code that I cut out to avoid clogging up this forum, since that was all working well, and accidentally cut out one of the 'rows'. So in my code I had an extra {'A', B', 'C', 'D'}, so my bad xD. Thanks for clearing up the loop as well, I copied it from another program I did earlier but couldn't figure out why it wasn't working in this one, and yeah I forgot to include the actual for loop line :/ thanks was really helpful. :) – Viliami Mahe Oct 01 '15 at 06:34
  • Ok, so those things are ok now, but now when I run it, it says that for the function displayAvailability - seatAvailability was not declared in this scope... any idea? :/ – Viliami Mahe Oct 01 '15 at 06:56
1
'row' was not declared in this scope    line 28

Where are your declaration of row and column ? You would need :

private:
int row;
int column;

in your class, and then initialize them either in the constructor or in the function that use them.

PlaneSeats::PlaneSeats()
{
    seatAvailability[7][4] = {{'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'},
                   {'A', 'B', 'C', 'D'}};
}

You can not initialize like this. You have to initialize each dimension manually.

blakelead
  • 1,780
  • 2
  • 17
  • 28
1

What is row? Local variable, member? It is not declared. (And only 6 of your rows are initialized.) Try this to iterate through array:

static const int NUM_ROW = 7;
static const int NUM_COL = 4;
char seatAvailability[NUM_ROW][NUM_COL];
/* .. */
    for( int row = 0; row < NUM_ROW; ++row )
    {
        for( int col = 0; col < NUM_COL; ++col )
        {
            std::cout << "\t" << seatAvailability[row][col];
        }
        std::cout << std::endl;
    }

Later try a dynamic array, e. g.:

std::vector< char > seats( NUM_ROW * NUM_COL, 0 );

It cannot be accessed the way seats[row][col], but seats[col+NUM_COL*row]. However it has its own benefits against static arrays.

renonsz
  • 571
  • 1
  • 4
  • 17
  • A light wrapper around the 1d vector with `char& operator()(size_t row, size_t column) {return vec[row * NUM_COL + column];}` hides the roughness of this approach. Usually much faster than a 2D vector, too. – user4581301 Oct 01 '15 at 06:32
0

Basics of array : The brace initializers are only available when declaring an array variable. So you cant do it your way.

So its better to assign values at the time of declaration, if values are known earlier.

Follow This link : Modified Code

secretgenes
  • 1,291
  • 1
  • 19
  • 39
  • 1
    Better form to embed the code in the post to stave off link rot. The goal is for these answers to last forever, not until the other server goes offline or shuffles it's linking. – user4581301 Oct 01 '15 at 06:33
  • @user4581301 : well i can understand your concern. But i've already mentioned what modification needed to be done in the above code by mentioning the basics of array. By providing direct answer is not the ri8 way. At least after getting an idea he should try for better understanding. – secretgenes Oct 01 '15 at 06:40
0

Best way to use a vector and print it iterating through the elements without knowledge of it's length is illustrated here:

    vector<vector<int>> mat {{11, 12, 13},{21, 22, 23},{31, 32, 33}};

for(auto line : mat)
{
    for(auto element : line)
    {
        cout<<element<< " ";
        }
   cout<<"\n";
 }
Artem
  • 79
  • 9