2D arrays and Coordinates
An answer to this question on Stack Overflow.
Question
I'm trying to just print space in my "canvas" ( with coordinates (2,2) for example) by editing my 80x20 grid made by █ blocks in the console window.
Please suggest me better ways of creating the grid in the first place ( I've just learned for-each loops)
Why do I get those 3 characters after running the program ?
Why isn't the space on the (2,2) block but obviously on the first row somewhere in the mid ?
Code :
#include <iostream>
int main()
{
uint8_t block {219}; // █
uint8_t space {32}; // ' '
uint8_t screen[80][20] {};
for (auto &row : screen) // make the "canvas"
for (auto &col : row)
col = block;
for (int row = 1; row <= 80; ++row)
{
for (int col = 1; col <= 20; ++col)
{
if (col == 2 && row == 2)
screen[row][col] = space;
}
}
std::cout << *screen;
return 0;
}
Answer
Some issues:
- C++ uses 0-based indexing. You want
for (int row = 0; row < 80; ++row). - You are looping through the entire array just to add a space, why not use
screen[2][2]=space? - You are printing the entire array to the screen, but the array does not include newlines, so you are relying on the console to wrap, is this a safe assumptions?
- Your string does not include the required null-termination, so extra characters are printed.
- You have ordered your array as column-major. I suspect you'll want to use row-major instead.
Since you're using C++, I'd probably write your code like this:
#include <iostream>
#include <vector>
class Screen {
public:
typedef uint8_t schar;
std::vector<schar> data; //Store data in a flat array: increases speed by improving caching
int width;
int height;
Screen(int width, int height, schar initchar){
this->width = width; //'this' refers to the current instantiation of this object
this->height = height;
data.resize(width*height,initchar); //Resize vector and set its values
}
schar& operator()(int x, int y){
return data[y*width+x];
}
void setAll(schar initchar){
std::fill(data.begin(),data.end(),initchar);
}
void print() const {
std::cout<<"\033[2J"; //ANSI command: clears the screen, moves cursor to upper left
for(int y=0;y<height;y++){
for(int x=0;x<width;x++)
std::cout<<data[y*width+x];
std::cout<<"\n"; //Much faster than std::endl
}
std::cout<<std::flush; //Needed to guarantee screen displays
}
};
int main(){
const int WIDTH = 80;
const int HEIGHT = 20;
uint8_t block {219}; // █
uint8_t space {32}; // ' '
Screen screen(WIDTH,HEIGHT,block);
screen(2,2) = space;
screen.print();
return 0;
}
