Simple C++ Program with Multidimensional Array Errors? - c++

When running the following code, I am attempting to update a Tic Tac Toe game board.
When you type in 3 as a column, it sets 2 X's or O's in the game board.
Here is an example of the output
* * *
* * *
* * *
X: Select a Row: 1
X: Select a Col: 3
* * X
X * *
* * *
Here is the desired output
* * *
* * *
* * *
X: Select a Row: 1
X: Select a Col: 3
* * X
* * *
* * *
Here is the code
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int rowSelect = 0;
int colSelect = 0;
char turn = 'X';
char rowcol[2][2];
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
rowcol[i][j] = '*';
}
}
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
cout << rowcol[i][j] << " ";
}
cout << endl;
}
cout << endl;
while (true)
{
cout << turn << ": Select a Row: ";
cin >> rowSelect;
while (rowSelect < 1 || rowSelect > 3)
{
cout << "I cannot accept that value, try again!" << endl;
cout << endl;
cout << turn << ": Select a Row: ";
cin >> rowSelect;
}
cout << turn << ": Select a Col: ";
cin >> colSelect;
while (colSelect < 1 || colSelect > 3)
{
cout << "I cannot accept that value, try again!" << endl;
cout << endl;
cout << turn << ": Select a Col: " << endl;
cin >> colSelect;
}
rowcol[rowSelect-1][colSelect-1] = turn;
if (turn == 'X')
{
turn = 'O';
}
else
{
turn = 'X';
}
for(int i=0; i < 3; i++)
{
for(int j=0; j < 3; j++)
{
cout << rowcol[i][j] << " ";
}
cout << endl;
}
}
system("PAUSE");
return 0;
}
Thanks!
-Mike

The problem is the array. Although arrays are accessed using zero based indices, the definition requires the actual number of elements for which to reserve space.
You defined rowcol as:
char rowcol[2][2]; // This defines a 2 x 2 array
You should have defined rowcol as:
char rowcol[3][3]; // This defines a 3 x 3 array
Hope this helps!
Keith

Your rowcol array needs to be 3x3:
char rowcol[3][3];

char rowcol[2][2];
In all the cases, i, j must iterate only until < 2 since it is a 2x2 array.

Your array only holds 2 elements per row, while your loop runs through three rows and three columns. You seem to be confused on how arrays are numbered, an array with 2 elements would be accessed using elements[0] and elements[1], because 0 is the first number in programming(not 1). you need to declare an array of THREE elements, and access them using [0] [1] and [2].
FIX: change to char Array[3][3];

Related

Print 2D array in reverse (C++)

Write a program that reads 12 integers into a 2D integer array with 4 rows and 3 columns. The program then outputs the 2D array in reverse order according to both rows and columns.
Ex: If the input is:
5 7 3
6 4 3
5 6 9
5 2 8
then the output is:
8 2 5
9 6 5
3 4 6
3 7 5
For coding simplicity, output a space after every integer, including the last one on each row.
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for(i = 0; i < ROWS; i++){
for(j = 0; j < COLS; j++){
cin>>arr[i][j];
}
}
cout << arr[3][2] << " " << arr[3][1] << " " << arr[3][0] << " " << endl;
cout << arr[2][2] << " " << arr[2][1] << " " << arr[2][0] << " "<< endl;
cout << arr[1][2] << " " << arr[1][1] << " " << arr[1][0] << " "<< endl;
cout << arr[0][2] << " " << arr[0][1] << " " << arr[0][0] << " "<< endl;
return 0;
}
I ended up having to hardcode this question because I couldnt find a way to reverse the 2D array with a loop and get it to be outputted in the form of a graph. Is there a way i could reverse the 2D array using for loops and would it be possible to be able to change the amount of rows and columns and still output the corresponding graph of values?
try this:
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// output the reversed array
for (int i = ROWS - 1; i >= 0; i--) {
for (int j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
You can reverse a 2D array using nested for loops, try
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
// Input the values into the 2D array
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// Reverse the rows and columns of the 2D array
for(i = ROWS - 1; i >= 0; i--) {
for(j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
As mentioned in comments below if you don't know ROWS and COLS size at compile time dynamically allocate the memory for 2D array(arr) in C++ using new operator.
There is very little point reading the data into a 2D array for this program. A std::vector would do the trick, sized with ROWS * COLS values. You then have the benefit of being able to read those dimensions from the user, which addresses the second part of your question.
size_t size = ROWS * COLS;
// Read data
std::vector<int> data;
data.reserve(size);
for (int value; std::cin >> value; )
{
data.push_back(value);
}
// Validate data
if (data.size() != size)
{
std::cerr << "Unexpected end of input!\n";
return EXIT_FAILURE;
}
When outputting, you can use a reverse iterator through the vector, and simply write a newline every COLS values.
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it << " ";
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
}
You can even easily fix the "space at the end of the line" problem by adjusting your output loop as follows:
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it;
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
else
{
std::cout << " ";
}
}

Unable to pass 2D character array to function(C++)

I am trying to pass a 2-D character array to a function however vs code gives me the following error message:
cannot convert 'char ()[3]' to 'char ()[10]'gcc
Here is the code:
#include<string>
using namespace std;
void NodeDetect(char grid[][3], int height, int width)
{
cout << "\nThe grid output:\n";
for(int i = 0; i < height; ++i)
{
for(int j = 0; j < width; ++j)
if(grid[i][j] == '0')
{
cout << '\n' << i << '\t' << j << ", ";
if(grid[i][j + 1] == '0' && (j + 1) < width)//right neighbour
cout << i << '\t' << (j + 1) << ", ";
else if(grid[i][j + 1] == '.' || (j + 1) == width)
cout << "-1 -1, ";
if(grid[i + 1][j] == '0' && (i + 1) < height)//bottom neighbour
cout << (i + 1) << '\t' << j << ", ";
else if(grid[i + 1][j] == '.' || (i + 1) == height)
cout << "-1 -1";
}
cout << '\n';
}
}
int main()
{
string line;
char grid[3][3];
int height, width; //height = rows
cout << "Enter the height and the width:\t";//width = columns
cin >> height >> width;
cout << "\nEnter the strings:\n";
for(int i = 0; i < height; ++i)//initializing the grid
cin >> grid[i];
/*
cout << "\nThe grid:\n";
for(int i = 0; i < height; ++i) //displaying the grid
{
for(int j = 0; j < width; ++j)
cout << grid[i][j] << '\t';
cout << '\n';
}
*/
NodeDetect(grid, height, width);
return 0;
}
I am trying to pass the 2D array grid to the function NodeDetect
If you want to pass a plain old C-array to a function in C++, you have 2 possibilities.
Pass by reference
Pass by pointer
It seems that you want to pass by reference. But you are using the wrong syntax.
Please see:
void function1(int(&m)[3][4]) // For passing array by reference
{}
void function2(int(*m)[3][4]) // For passing array by pointer
{}
int main()
{
int matrix[3][4]; // Define 2 dimensional array
function1(matrix); // Call by reference
function2(&matrix); // Call via pointer
return 0;
}
What you pass to the function is a decayed pointer to array of char.
Simply correct the syntax and it will work.
Additional hint:
Do not use plain C-style arrays in C++. Never. Please use STL containers.

How to make exception in for loop?

The code below prints a box with the intergers the user inputs. I need to make it hollow to only display the full length of the first and last line of the box. like width = 5 height = 4
Example Output:
00000
0 0
0 0
00000
Source:
int main ()
{
int height;
int width;
int count;
int hcount;
string character;
cout << "input width" << endl;
cin >> width;
cout << "input height" << endl;
cin >> height;
cout << "input character" << endl;
cin >> character;
for (hcount = 0; hcount < height; hcount++)
{
for (count = 0 ; count < width; count++)
cout << character;
cout << endl;
}
}
I do not know how to change the loop condition for the width to make it work.
I think you can test whether you are in the first or last row, and first or last column.
Example:
#include <string>
#include <iostream>
int main ()
{
using namespace std; // not recommended
int height;
int width;
string character;
cout << "input width" << endl;
cin >> width;
cout << "input height" << endl;
cin >> height;
cout << "input character" << endl;
cin >> character;
for (int i = 0; i < height; i++)
{
// Test whether we are in first or last row
std::string interior_filler = " ";
if (i == 0 || i == height - 1)
{
interior_filler = character;
}
for (int j = 0; j < width; j++)
{
// Test whether are in first or last column
if (j == 0 || j == width -1)
{
cout << character;
} else {
cout << interior_filler;
}
}
// Row is complete.
cout << std::endl;
}
}
Here is the output:
$ ./a.out
input width
10
input height
7
input character
*
OUTPUT
**********
* *
* *
* *
* *
* *
**********
Add an if to the cout << character line. If we're not in the first row or column, output a space instead of the character.

Simple Nested Loop Issue. * Shape *

I am having a brain shock right now so I wanted to ask very simple question.
Currenly, I am trying to print out starts like this
when input is 7 , the output is
*
**
*
**
*
**
*
and here my code is , it prints 14 times instead of 7 or when I put N/2 it doesnt print the odd number.
#include <iostream>
using namespace std;
int main () {
int N;
cout << " Please enter N " ;
cin >> N;
for (int i = 0; i < N ; i++) {
cout << "*" << endl;
for (int j = 0; j < 2; j++) {
cout << "*" ;
}
cout << endl;
}
}
For each N you are printing two lines, with single * and another with two *. Instead just print single line with either one or two star based on the line is odd or even.
#include <iostream>
int main ()
{
unsigned int N;
cout << " Please enter N " ;
cin >> N;
for(unsigned int i = 0; i < N; ++i)
{
if(i%2 == 0)
{
std::cout << "*" << std::endl;
}
else
{
std::cout << "**" << std::endl;
}
}
}
(Untested code)
Can't you just go like this :
for (int i = 0; i < N ; i++) {
if (i%2 == 0)
{
cout << "**" << endl;
}
else
{
cout << "*" << endl;
}
}
In your case, for each of your N iterations, you print , jump to a new line, print *, and then jump to a new iteration. So 14 lines when N is 7.
It's because each time the first for loop runs, the second loop also runs. You can't print out both * and ** and expect it to print N times (it will always print 2 * N times). You need to print either * or **, but not both at the same time. Simple example:
bool alternate = false;
for (int i = 0; i < N ; i++) {
if (alternate) {
cout << "*" << endl;
} else {
cout << "**" << endl;
}
alternate = !alternate;
}
You could remove the alternate variable and check if i is even or odd (with something like i & 1), but I used the alternate variable to help make it clearer.
For each complete iteration of your outer loop the following is printed:
*
**
If you run that loop 7 times then you'll get 14 rows. try this instead, no need for the inner loop:
for (int i = 0; i < N ; i++) {
cout << "*" << endl;
cout << "**" << endl;
}

Print array 3 lines

I am trying to print this array of 9 elements out in 3 lines.
I want to print it out in 3 lines with 3 rows such as .
xxx
xxx
xxx
But i am not sure how to tackle that.
void ticTacToeBoard ()
{
for (int i = 0; i < 9; i++)
{
cout << ticTacBoard[i] << " ";
}
}
I like to be verbose with my loops, so try this:
void ticTacToeBoard ()
{
for (int y = 0; y < 3; y++)
{
for (int x = 0; i < 3; x++)
{
cout << ticTacBoard[3 * y + x] << " ";
}
cout << endl;
}
}
Basically, I iterate over your board in rows (y), and then in columns (x), allowing me to print each cell and control the flow.
I just print a newline (endl) after each row.
Change ticTacBoard to a two dimensional array and do
using namespace std;
int main()
{
int ticTacBoard[3][3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << ticTacBoard[i][j] << " ";
}
cout << endl;
}
return 0;
}
A two dimensional array will be easier to understand.
Use the modulo operator to detect every third iteration. Then print a newline.
void ticTacToeBoard ()
{
for (int i = 0; i < 9; i++)
{
cout << ticTacBoard[i] << " ";
if((i + 1) % 3 == 0) {
cout << endl;
}
}
}
You can switch frot the offset in a single-dimensional array (say i) to the offset in a bi-dimensional via this simple formula:
row = i div width
column = i mod width
So, basically:
for(int i = 0; i < 9; i++) {
cout << ticTacBoard[i];
if(i % 3 == 2)
cout << endl;
else
cout << ' ';
}