Arrays with for loops

The below is my program. While displaying the 8x6 board, my first row is not aligned with the other rows. What is wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  #include <iostream>
#include <iomanip>
using namespace std;

const int rows = 8;
const int columns = 6;


char matrix[rows][columns] = { '.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.',
								'.','.','.','.','.','.' };


void display()
{
	cout << "1" << setw(3) << "2" << setw(3) << "3" << setw(3) << "4" << setw(3) << "5" << setw(3) << "6" << endl;
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < columns; j++)
		{
			cout << matrix[i][j] << setw(3);
		}
		cout << endl;
	}
	cout << "1" << setw(3) << "2" << setw(3) << "3" << setw(3) << "4" << setw(3) << "5" << setw(3) << "6" << endl;
}



int main()
{
	

	display();
	system("pause");
	
	return 0;
}
Move the ordering of when you call setw(3) around. Add std::left if you want left justification.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void display()
{
	int width = 3;
	cout << std::left << setw(width) << "1" << setw(width) << "2" << setw(width) << "3" << setw(width) << "4" << setw(width) << "5" << setw(width) << "6" << '\n';
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < columns; j++)
		{
			cout << setw(3) << matrix[i][j];
		}
		cout << '\n';
	}
	cout << setw(width) << "1" << setw(width) << "2" << setw(width) << "3" << setw(width) << "4" << setw(width) << "5" << setw(width) << "6" << '\n';
}


PS: the output buffer must flush every time you send :endl: to it. If you're printing a lot of new lines, prefer just '\n'.
Last edited on
Apparently cout'ing endl doesn't eat the setw(3) so it's still in effect for the first value printed on the next row. Using '\n' instead of endl fixes that. Or you could throw a setw(0) in there. Alternatively you can output the first value of a row before the column loop and put the setw in it's usual position before the output value. I'd probably write it more like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <algorithm>  // fill
#include <iostream>
#include <iomanip>
using namespace std;

const int Rows    = 8;
const int Columns = 6;
const int Width   = 3;

void display(char matrix[][Columns]) {
    cout << '1';
    for (int i = 2; i <= Columns; i++) cout << setw(Width) << i;
    cout << '\n';
    for (int i = 0; i < Rows; i++) {
        cout << matrix[i][0];
        for (int j = 1; j < Columns; j++)
            cout << setw(Width) << matrix[i][j];
        cout << '\n';
    }
    cout << '1';
    for (int i = 2; i <= Columns; i++) cout << setw(Width) << i;
    cout << '\n';
}

int main() {
    char matrix[Rows][Columns];
    fill(&matrix[0][0], &matrix[Rows][0], '.');
    display(matrix);
}

Or if you want row numbers, too:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <algorithm>  // fill
#include <iostream>
#include <iomanip>
using namespace std;

const int Rows    = 8;
const int Columns = 6;
const int Width   = 3;

void display(char matrix[][Columns]) {
    cout << ' ' << setw(Width) << '1';
    for (int i = 2; i <= Columns; i++) cout << setw(Width) << i;
    cout << '\n';
    for (int i = 0; i < Rows; i++) {
        cout << i + 1;
        for (int j = 0; j < Columns; j++)
            cout << setw(Width) << matrix[i][j];
        cout << setw(Width) << i + 1 << '\n';
    }
    cout << ' ' << setw(Width) << '1';
    for (int i = 2; i <= Columns; i++) cout << setw(Width) << i;
    cout << '\n';
}

int main() {
    char matrix[Rows][Columns];
    fill(&matrix[0][0], &matrix[Rows][0], '.');
    display(matrix);
}

Your board is also a 1d array. It is not actually an array of 6 x 8.
ntchambers wrote:
Your board is also a 1d array. It is not actually an array of 6 x 8.

You're allowed to leave out the inner braces when initializing a multi-dimensional array.

1
2
3
int a[2][3][2] = {0,1,2,3,4,5,6,7,8,9,10,11};
// same as
int a[2][3][2] = {{{0,1},{2,3},{4,5}},{{6,7},{8,9},{10,11}}};

Last edited on
For arrays (not MD pointer constructs) you can collapse them to 1-d always. Not just to init, but to iterate as well.

int a[2][3][2] = {0,1,2,3,4,5,6,7,8,9,10,11};
int * ip = &(a[0][0][0]); // being extra explicit
for(z = 0; z < 2*3*2; z++) //also extra explicit
ip[z] = 12-z;

cout << a[1][1][1] << endl; //changed!
this happens because arrays are assured to be a single block of memory, in a specific order for the dimensions but all the values are sequential in one block. So if you grab the first value, you can just iterate. Or memcpy. etc. Since you can't do this with dynamic memory, it is not terribly useful for larger constructs though.
Last edited on
I should have mentioned that even though leaving out the inner braces is allowed in C++, it is not (technically) allowed in C. I have no idea why since it's obviously exactly the same situation. As jonnin said, it's well defined how the 1D version maps to the multi-D version.
closed account (E0p9LyTq)
You're allowed to leave out the inner braces when initializing a multi-dimensional array.

I use multiple layers of braces when creating a MD container for human readability. So I don't get confused.

I'm more likely to create a MD vector over a C-style array. Easier to deal with, especially if passing into a function.

I've created simulated MD containers as a 1D container, and as real MD containers. Memory layout is far less of a concern to me most times than ease of usage.
Yes, unless the fragmentation of memory is a performance hit you can't allow, that is the cleaner and better way.

/shrug.
double matrix [3][3] =
{
1,2,3,
4,5,6,
7,8,9
};

^^^ perfectly human readable via alignment.
as with nearly anything, you can make it look nice if you want to do so.
adding a third+ dimension is harder, and I am with you: the extra braces is probably better looking there.


Last edited on
Topic archived. No new replies allowed.