-1

I am trying to print a 2d matrix in c++. I have a 2D array of integers. The output looks like this:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 
0 0 0 0 0 0 0 0 0 0 60 60 60 60 60 60 60 60 60 60 100 100 100 100 100 100 100 100 100 100 160 

My code simply does 2 loops and adds an space after each number (and a newline after every row). Is there an easy way to print nicely formatted matrix in cpp. Something that would be more readable like so:

0 0 0 0 0 0 0  0  0   0   0 
0 0 0 0 0 0 60 60 60  60  60
0 0 0 0 0 0 60 60 100 100 160

Code:

for(int i = 0; i <= n ; i++){
    for(int w = 0; w <= W ; w++){
        std:cout<<some_array[i][w]<<"   ";
    }
    std::cout << std::endl;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Abhijeet Khangarot
  • 1,281
  • 1
  • 16
  • 25
  • Does this answer your question? [How to print 2D Arrays in C++?](https://stackoverflow.com/questions/12311149/how-to-print-2d-arrays-in-c) – Muhteva Oct 09 '21 at 09:41
  • 1
    `Is there an easy way` No. But do it, write code, iterate over each element, get the element printed width, remember the most wide element in each column, reiterate over each element again, pad elements with spaces to extracted column width. – KamilCuk Oct 09 '21 at 09:45
  • That's nice, I'll attach the code to do it in a bit, looking for an easy way as it looks like something that a lot of people might need frequently. – Abhijeet Khangarot Oct 09 '21 at 09:53
  • `for(int i = 0; i <= n ; i++)` -- Any loop that has `<=` as the loop condition is suspicious in that it has all of the signs of being an off-by-one buffer overrun. – PaulMcKenzie Oct 09 '21 at 09:58
  • Just use something like `std:cout<< setfill(5) << some_array[i][w];` to print values in a field of size 5. – Jean-Baptiste Yunès Oct 09 '21 at 13:57

2 Answers2

1

This overload of the output stream operator will do the formatting for you. And then the code where you do the output will look quite clean.

#include <iostream>

template<typename type_t, std::size_t rows_v, std::size_t cols_v>
std::ostream& operator<<(std::ostream& os, type_t (&arr)[rows_v][cols_v])
{
    // loop over the rows
    for (const auto& row : arr)
    {
        // to print a comma between values
        bool comma{ false };

        // loop over the values in the row
        for (const auto& value : row)
        {
            if (comma) os << ", ";
            os << value;
            comma = true;
        }
        os << "\n";
    }

    return os;
}

int main()
{
    int arr[2][3]{{0,1,2},{4,5,6}};
    std::cout << arr << "\n";
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
0

Quick code that does this, could be made better:

#include <iostream>
#include <string>

int main()
{
    int maxwidth = 0;
    int sz;
    std::string s;

    int K[3][31] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 160}};

    for (int i = 0; i < 3; i++)
    {
        for (int w = 0; w < 31; w++)
        {
            s = std::to_string(K[i][w]);
            sz = s.size();
            maxwidth = std::max(maxwidth, sz);
        }
    }

    maxwidth++; // we need to print 1 extra space than maxwidth

    for (int i = 0; i < 3; i++)
    {
        for (int w = 0; w < 31; w++)
        {
            std::cout << K[i][w];
            s = std::to_string(K[i][w]);
            sz = (maxwidth - s.size());
            while (sz--)
                std::cout << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

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   60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  60  
0   0   0   0   0   0   0   0   0   0   60  60  60  60  60  60  60  60  60  60  100 100 100 100 100 100 100 100 100 100 160 
Abhijeet Khangarot
  • 1,281
  • 1
  • 16
  • 25