Home > OS >  Creating a "#" border outside my 2d array
Creating a "#" border outside my 2d array

Time:07-18

Hi I'm currently trying to create a border for my dynamic 2D array, I managed to create the left and right side border of my 2d array grid. But I currently have trouble figuring out on how to do it for the top and bottom side of the 2d array grid.

Is the method I'm currently trying a good way to achieve this? Any help or suggestion would be greatly appreciated thanks!

void displayCity(int minX, int maxX, int minY, int maxY)
{ 
    //Allocate the array.
    int** twod = new int* [maxX];
    for (int i = 0; i < maxX; i  )
    {
        twod[i] = new int[maxY];
    }

    for (int i = 0; i< maxX;   i)
    {
        cout << '#';
        for (int j = 0; j < maxY;   j)
        {
            twod[i][j] = 0;
            cout << twod[i][j] << ' ';
        }
        cout << setw(1) << '#';
        cout << endl;
    }

    //Deallocate the array.
    for (int i = 0; i < maxX;   i) 
    {
        delete[] twod[i];
    }
    delete[] twod;
}

This is my current 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 0 0 0 0 0 0 0 #

CodePudding user response:

Don't use "new/delete" unless you really need to. (C core guidelines). Instead rely on datastructures from stl, like std::vector (for dynamically allocated arrays). For example like this :

#include <vector>
#include <iostream>
#include <string>

// City class to hold city data (but not to render it).
class City
{
public:
    City(std::size_t width, std::size_t height) :
        m_width{ width },
        m_height{ height },
        m_city_blocks(height,std::vector<int>(width))
    {
    }

    const auto& city_blocks() const noexcept
    {
        return m_city_blocks;
    }
    
    const auto width() const noexcept
    {
        return m_width;
    }

    const auto height() const noexcept
    {
        return m_height;
    }

private:
    std::size_t m_width;
    std::size_t m_height;

    // dynamically allocated arrays are best handled by vector
    // not by using new (new/delete are no longer recommended)
    // use STL containers or std::make_unique
    std::vector<std::vector<int>> m_city_blocks;
};


// Seperate class for rendering cities
class Renderer
{
public:
    void ShowCity(const City& city)
    {
        // make a string with enougn '#' to draw bottom and top line
        std::string border(2ul * city.width()   3ul, '#');

        // output to screen
        std::cout << border << "\n";

        // loop over all rows in the city's blocks using a range based for loop
        // use const since rendering should not modify the state of the city blocks 
        // only show them.
        for (const auto& row : city.city_blocks())
        {
            std::cout << "# ";

            // loop over all values and display them
            for (const auto& value : row)
            {
                std::cout << value << " ";
            }
            std::cout << "#\n";
        }

        std::cout << border << "\n";
    }
};

int main()
{
    // make a 5*5 city
    City city{ 5ul,5ul };

    // create a renderer to display the city
    Renderer renderer;
    
    renderer.ShowCity(city);

    return 0;
}

CodePudding user response:

Your way of drawing the border is rather inflexible because you mix the data, and formatting and output of the data with formatting and output of the border.

Also your borders are not straight lines when the numbers have different number of digits.

I suggest you to first gather all the output to be printed inside borders, then inspect it to see how many lines there are and how long the lines are. Then you know where to print the border:

#include <sstream>
#include <iomanip>
#include <vector>
#include <iostream>

void print_with_border(std::stringstream& str,char border='#') {
    std::vector<std::string> output;    
    size_t max_len = 0;
    std::string line;
    while(std::getline(str,line)) {
        output.push_back(line);
        max_len = std::max(max_len,line.size());
    }

    std::cout << std::string(max_len 4,border) << "\n";
    for (const auto& l : output) {
        std::cout << border << " " << std::setw(max_len) << std::left << l <<  " " << border << "\n";
    } 
    std::cout << std::string(max_len 4,border) << "\n";
}


int main() {
    std::stringstream ss;
    ss <<"hello \n world";
    print_with_border(ss);
}

Output:

##########
# hello  #
# world  #
##########

To print contents of a 2d array you just have to pipe the contents of the array with desired formatting into a stringstream.

  • Related