Does row and column of 2D arrays start at 0? - c++

Does int myarray[7][7] not create a box with 8x8 locations of 0-7 rows and columns in C++?
When I run:
int board[7][7] = {0};
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
cout << board[i][j] << " ";
}
cout << endl;
}
I get output:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 146858616 1 0 0 146858832 1 1978920048
So the 8 columns seem to work, but not the 8 rows.
If I change it to int board[8][7] = {0}; it works on mac CodeRunner IDE, but on linux Codeblocks I get:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1503452472
Not sure what's going on here.

Two dimensional arrays are not different to the one dimensional ones in this regard: Just as
int a[7];
can be indexed from 0 to 6,
int a2[7][7];
can be indexed from 0 to 6 in both dimensions, index 7 is out of bounds. In particular: a2 has 7 columns and rows, not 8.

int board[7][7]; will only allocate 7x7, not 8x8. When it's allocated, you specify how many, but indexes start at 0 and run to the size - 1.
So based on your source, I would say you really want int board[8][8].

int board[7][7] = {0}; creates a 7x7 array. You are going out of bounds in your loop. Change it to int board[8][8] = {0};

int board[8][7] = {0};
When you do as above, you created only 8 rows and 7 columns.
So your loop condition should be as follows:
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 7; j++)
{
If you try as follows system will print garbage values from 8th columns
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{

Araay starts from zero means that it will have n-1 elements not n+1 elements
try
int a[8][8] = {}
i = 0
j = 0
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
a[i][j] = 0;
}
}

Related

Loading a 2D array from an input file into a Function

I am having trouble loading a 10x10 array from an input file and storing it into an array. I have written this so far:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS]) //Function to load in image
{
ifstream inputs;
int i,j;
inputs.open(imagefile.c_str());
getline(inputs, imagefile[i][j]);
inputs.ignore(10000,'\n');
if (inputs.is_open())
{
for( i=0; i < MAXROWS; i++ )
{
for ( j=0; i < MAXCOLS; j++ )
{
inputs >> image[i][j];
}
}
}
inputs.close();
}
The void LoadImage function and was given to me with those specific parameters to use or the main function will not execute.
An example of an input file:
#Sample Image--1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Where I have to get rid of the header of the input file before building the array.
If I compile what I have now I get the "error: invalid types ‘const char[int]’ for array subscript
getline(inputs, imagefile[i][j]);"
I understand why I am getting the error, but I do not know how to fix it.
I appreciate any help I can get!
The code is generally OK, just following the comments and fixing a few small mistakes should work.
Note specially the terminating condition for the following loop:
for ( j=0; i < MAXCOLS; j++ )
Should be instead:
for ( j=0; j < MAXCOLS; j++ )
This is the reason why you're getting an infinite loop.
Here's the complete code:
#include <iostream>
#include <fstream>
#include <string>
#define MAXROWS 10
#define MAXCOLS 10
using namespace std;
void LoadImage(const string imagefile, int image[MAXROWS][MAXCOLS]) //Function to load in image
{
ifstream inputs;
int i,j;
inputs.open(imagefile.c_str());
if (inputs.is_open())
{
for( i=0; i < MAXROWS; i++)
{
for ( j=0; j < MAXCOLS; j ++)
{
std::string str;
inputs >> image[i][j];
}
}
}
inputs.close();
}
void PrintImage(int image[MAXROWS][MAXCOLS])
{
int i,j;
for(i = 0; i < MAXROWS; i++)
{
for (j = 0; j < MAXCOLS; j ++)
{
cout << image[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int image[MAXROWS][MAXCOLS] = {0,};
LoadImage ("img.mtx", image);
PrintImage (image);
}
And testing:
$ cat img.mtx
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
$ g++ main.cpp && ./a.out
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
The line
getline(inputs, imagefile[i][j]);
does not make sense.
If you want to ignore the first line of the input file, then you should simply use inputs.ignore, as you are already doing afterwards. So you can simply delete the line which calls getline.
Another problem is that the line
for ( j=0; i < MAXCOLS; j++ )
should probably be
for ( j=0; j < MAXCOLS; j++ )
i.e. you wrote i instead of j.

Initialize 2d Array at compile and allow user input

I am trying to declare an array that is sized at runtime/compile through an overload constructor.
private:
auto** arr = new int[n][n];
overloadConstruct(int n){
arr[n][n] = {0,0};
}
This does not work, it says the second n needs to be constant and auto is not allowed. Any help would be appreciated. I am not sure of all the rules with arrays, especially 2d arrays when doing this. I just need to be able to size a 2d array at runtime/compile through an input.
Use a vector of vectors instead:
#include <iostream>
#include <vector>
class Foo
{
public:
Foo( const int rowCount, const int colCount )
: m_2dArray( rowCount, std::vector<int>( colCount ) ) // initialize the vector
{ // member like this
}
void printArr() const
{
for ( size_t row = 0; row < m_2dArray.size( ); ++row )
{
for ( size_t col = 0; col < m_2dArray[ 0 ].size( ); ++col )
{
std::cout << m_2dArray[ row ][ col ] << " ";
}
std::cout << '\n';
}
}
private:
std::vector< std::vector<int> > m_2dArray; // the vector member
};
int main ()
{
int rowCount { };
int colCount { };
std::cout << "Enter row count: ";
std::cin >> rowCount;
std::cout << "Enter column count: ";
std::cin >> colCount;
std::cout << "\nThe contents of 2D array:\n";
Foo obj( rowCount, colCount ); // construct the object using user's input
obj.printArr( );
}
The output:
Enter row count: 10
Enter column count: 20
The contents of 2D array:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
As you can see, the user can enter the values at runtime.

Printing two-dimensional array

I have this two-dimensial array array[y][x] (where x is horizontal and y vertical):
3 2 0 0 0 0 0 0 0 0
1 4 3 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
2 4 0 0 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
4 2 5 1 0 0 0 0 0 0
1 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
2 3 0 0 0 0 0 0 0 0
And I need to print it like this:
3 1 2 2 1 4 1 2 2
2 4 4 4 3 2 3 3 3
3 5
1
How would I do this using c++?
Note that there are no empty lines. If the whole column only has zero's in them, there shouldn't be an endl
You need to iterate over and print out each element. You can flip the elements around by swapping the indices used to get the value out of the array.
#include<iostream>
#include<iomanip>
int gridWidth = 10;
int gridHeight = 10;
int cellWidth = 2;
for (int i = 0; i < gridHeight; i++){
bool anyVals = false;
for (int j = 0; j < gridWidth; j++){
int val = array[i][j]; //Swap i and j to change the orientation of the output
if(val == 0){
std::cout << std::setw(cellWidth) << " ";
}
else{
anyVals = true;
std::cout << std::setw(cellWidth) << val;
}
}
if(anyVals)
std::cout << std::endl;
}
Remember that if you swap i and j then you will need to swap gridWidth and gridHeight.
Just to avoid confusion std::setw(cellWidth) thing is a convenient way to print fixed-width text (like text that must always be two characters long). It takes whatever you print out and adds spaces to it to make it the right length.
Take the transpose of your matrix , make 2 loops(outer and inner ) and print only if the no is greater than zero and print space for every zero. when you go back again to the outer loop ,print new line .
Something like this should help you.
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
if (array[i][j] != 0)
cout << array[i][j];
else
cout << " ";
cout << endl;

How to compare two 2D arrays of different sizes in C++?

I am trying to implement a binary image matching algorithm. And I need to generate the C matrix given below.
Given a small pattern image A, I need to match it to large image row-by-row and column-by-column, to find the location where that pattern matches the most.
Given M x M sized pattern A:
0 0 1
0 1 1
1 1 1
and N x N sized input image B:
0 0 0 0 0 1 0 0
0 0 0 0 1 1 0 0
0 0 0 1 1 1 0 0
0 0 0 0 0 0 0 0
1 1 1 0 0 0 1 0
0 0 0 0 0 0 1 0
0 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0
the N x N sized output image C is the similarity of A with B at each row and column of B. Therefore C:
0 0 0 0 0 0 0 0
0 3 4 6 9 4 2 0
0 3 4 6 4 1 1 0
0 6 6 4 2 2 3 0
0 4 3 2 3 5 5 0
0 2 2 4 6 8 5 0
0 3 4 5 4 5 2 0
0 0 0 0 0 0 0 0
I am at stuck at the point where I need to compare the matrix A with B. I have made them as 2D arrays.
This is what I have done so far
for (int i = 0; i <3 ; i++)
{
for (int j = 0; j<3; j++)
{
for (int k = 0; k < 8; i++)
{
for (int s = 0; s < 8; j++)
{
if (A[i][j] == B[k][s])
{
count++;
}
}
}
}
whats your code or algorithm? You've 9 in the matrix, so
0 0 1
0 1 1
1 1 1
matches exactly. There's the coordinate pair you must be searching for.
typedef int** matrix;
struct position
{
int x;
int y;
position(int _x,int _y){ x = _x ; y= _y; }
}
// M &lt= N
//checks all MxM submatrices in NxN matrix B
//and compares them with NxN matrix A
position f(matrix A, int M , matrix B , int N)
{
int best_match_first_row = -1;
int best_match_first_column = -1;
int best_match_counted = -1;
for(int i=0; i &lt= N-M ; ++i)// iterate through the first elements of every
for(int j=0; j &lt= N-M ; ++j)// MxM submatrix
{
int match_count = 0;
for(int k=0 ; k &lt M ; ++k)//iterate through the submatrix
for(int l=0 ; l &lt M ; ++l)//and compare elements with matrix A
if( A[k][l] == B[i+k][j+l] ) ++match_count; //count if it matches
if(match_count > best_match_counted) //if we have a better match than before
{
best_match_counted = match_count; //store the new count as best.
best_match_first_row = i; //store the position of the
best_match_first_column = j; //first element in the submatrix
}
}
//returns the position of the first element of the most matching submatrix
return position( best_match_first_row , best_match_first_column )
}

Filling array from file won't work

I have made a 'Map' array and I am attempting to populate it from a 'map' file. On creation I assign the value '0' to each element of the array but the 'Map' file contains the following:
MAP:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I load the map using 'loadMap()'
loadMap():
void room::loadMap()
{
int x=0;
int y=0;
string line;
ifstream mapFile(NAME + "_MAP.txt");
while(!mapFile.eof())
{
for(int i=0; i<cellsY; i++)
{
getline(mapFile,line,'\n');
for(int j=0; j<cellsX; j++)
{
getline(mapFile,line,' ');
map[(cellsX*j) + cellsY] = atoi(line.c_str());
};
};
}
y = 10;
x = 15;
for(int i=0; i<y; i++)
{
cout << endl;
for(int j=0; j<x; j++)
{
cout << map[(x*j) + y];
};
};
}
In this example the elements are still assigned to '0', but I am trying to mimic the Map files layout.
For starters, you never test that any of the input works, nor
that the open succeeded. Then, in the outer loop, you read
a line from the file, and throw it away, before reading further
in the inner loop. And your calcule of the index is wrong.
What you're probably looking for is something like:
std::ifstream mapFile(...);
if ( !mapFile.is_open() ) {
// Error handling...
}
for ( int i = 0; mapFile && i != cellsY; ++ i ) {
std::string line;
if ( std::getline( mapFile, line ) ) {
std::istringstream text( line );
for ( int j = 0; j != cellsX && text >> map[cells X * i + j]; ++ j ) {
}
if ( j != cellsX ) {
// Error: missing elements in line
}
text >> std::ws;
if ( text && text.get() != EOF ) {
// Error: garbage at end of line
}
}
}
For the error handling, the simplest is just to output an
appropriate error message and continue, noting the error so you
can return some sort of error code at the end.
I think this is what you are looking for.
void room::loadMap()
{
int x=0;
int y=0;
ifstream mapFile(NAME + "_MAP.txt");
for(int i=0; i<cellsY; i++)
{
for(int j=0; j<cellsX; j++)
{
int v;
mapFile >> v;
if ( mapFile.eof() )
{
break;
}
map[(cellsX*j) + cellsY] = v;
}
}
y = 10;
x = 15;
for(int i=0; i<y; i++)
{
cout << endl;
for(int j=0; j<x; j++)
{
cout << map[(x*j) + y];
};
};
}