Home > OS >  How to format an 2d array of different type sized strings (e.g. x, xxx ,xx ,xxx) to look more square
How to format an 2d array of different type sized strings (e.g. x, xxx ,xx ,xxx) to look more square

Time:11-26

This is my code Does any one know how I can format it so it looks more like a square rather due to the different character sizes in each element.

1

int main() {
     string a[4][4]= {{"\xC9","\xCD","\xCD","\xBB"},
                     {"\xBA","p1","p2","\xBA"},
                     {"\xBA","100","p3","\xBA"},
                     {"\xC8","\xCD","\xCD","\xBC"}};
    printSquare(a);

this is my code but the output seems to look funny

enter image description here

CodePudding user response:

There's not really a shortcut here: you'll have to all bring them to the same length. Which length to choose: hard. You might first have to make all rows, then find the longest one, the format all rows to have the same length, then make the top and bottom bar.

You can do that with iostreams / stringstream in standard C . But it's really a pain. iostreams are simply not a good output formatting library.

I'd instead recommend using fmtlib, which supports format strings. So you can first format all your rows, and save the length of the longest

#include "fmt/format.h"
#include "fmt/ranges.h"
#include <algorithm>
#include <string>
#include <vector>
int main() {
  std::vector<std::vector<std::string>> data{
      {"p1", "p2"}, {"100", "p3"}, {"very long string"}};

  unsigned int longest_row = 0;
  for (const auto &row : data) {
    const std::string this_row =
        fmt::format("{}", fmt::join(row.begin(), row.end(), ""));
    unsigned int rowlength = this_row.length();
    longest_row = std::max(longest_row, rowlength);
  }
  // Explanation: Print corner - empty string - corner, but pad "empty string"
  // longest row times with "middle piece" > is for right-aligned padding
  // (doesn't matter for empty string)
  fmt::print("╔{:═>{}}╗\n", "", longest_row);

  for (const auto &row : data) {
    // ^ is for centered padding
    // fill with " " (we could omit this, but I think it's clearer)
    const std::string this_row =
        fmt::format("{}", fmt::join(row.begin(), row.end(), ""));
    fmt::print("║{: ^{}}║\n", this_row, longest_row);
  }

  fmt::print("╚{:═>{}}╝\n", "", longest_row);
}

Remarks:

  1. Replaced your string arrays with std::vectors. Just more convenient.
  2. No need to use escape sequences to include unicode characters in strings, unless your compiler sucks.
  • Related