Skip to main content
This example demonstrates Tabulate’s excellent support for Unicode characters, including multi-byte characters from various writing systems around the world.

Complete Example

#include <tabulate/table.hpp>
using namespace tabulate;
using Row_t = Table::Row_t;

int main() {
  Table table;

  table.format()
      .corner("♥")
      .font_style({FontStyle::bold})
      .corner_color(Color::magenta)
      .border_color(Color::magenta);

  table.add_row(Row_t{"English", "I love you"});
  table.add_row(Row_t{"French", "Je t'aime"});
  table.add_row(Row_t{"Spanish", "Te amo"});
  table.add_row(Row_t{"German", "Ich liebe Dich"});
  table.add_row(Row_t{"Mandarin Chinese", "我爱你"});
  table.add_row(Row_t{"Japanese", "愛してる"});
  table.add_row(Row_t{"Korean", "사랑해 (Saranghae)"});
  table.add_row(Row_t{"Greek", "Σ΄αγαπώ (Se agapo)"});
  table.add_row(Row_t{"Italian", "Ti amo"});
  table.add_row(Row_t{"Russian", "Я тебя люблю (Ya tebya liubliu)"});
  table.add_row(Row_t{"Hebrew", "אני אוהב אותך (Ani ohev otakh)"});

  // Column 1 is using multi-byte characters
  table.column(1).format().multi_byte_characters(true);

  std::cout << table << std::endl;
}

Output

The table will render beautifully with proper character alignment:
♥─────────────────♥────────────────────────────────────────♥
│ English         │ I love you                             │
♥─────────────────♥────────────────────────────────────────♥
│ French          │ Je t'aime                              │
♥─────────────────♥────────────────────────────────────────♥
│ Spanish         │ Te amo                                 │
♥─────────────────♥────────────────────────────────────────♥
│ German          │ Ich liebe Dich                         │
♥─────────────────♥────────────────────────────────────────♥
│ Mandarin Chinese│ 我爱你                                  │
♥─────────────────♥────────────────────────────────────────♥
│ Japanese        │ 愛してる                                │
♥─────────────────♥────────────────────────────────────────♥
│ Korean          │ 사랑해 (Saranghae)                      │
♥─────────────────♥────────────────────────────────────────♥
│ Greek           │ Σ΄αγαπώ (Se agapo)                     │
♥─────────────────♥────────────────────────────────────────♥
│ Italian         │ Ti amo                                 │
♥─────────────────♥────────────────────────────────────────♥
│ Russian         │ Я тебя люблю (Ya tebya liubliu)        │
♥─────────────────♥────────────────────────────────────────♥
│ Hebrew          │ אני אוהב אותך (Ani ohev otakh)         │
♥─────────────────♥────────────────────────────────────────♥

Key Features

Multi-Byte Character Support

The critical setting for proper Unicode rendering:
// Enable multi-byte character support for columns with Unicode text
table.column(1).format().multi_byte_characters(true);
Without multi_byte_characters(true), the table may appear misaligned because multi-byte characters (like Chinese, Japanese, Korean, Arabic, Hebrew, etc.) take up more bytes than they do display width.

Custom Corner Characters

Make your tables unique with Unicode corner symbols:
table.format()
    .corner("♥")                      // Use heart symbol for corners
    .corner_color(Color::magenta);    // Color the corners
table.format().corner("♥");
You can use any Unicode character for corners, borders, and column separators to create unique table styles.

Border Styling

The entire border can be styled with color and custom characters:
table.format()
    .corner("♥")
    .corner_color(Color::magenta)
    .border_color(Color::magenta)
    .font_style({FontStyle::bold});

Supported Writing Systems

Tabulate correctly handles width calculations for:

East Asian Scripts

table.add_row(Row_t{"Chinese", "你好世界"});
table.add_row(Row_t{"Japanese", "こんにちは世界"});
table.add_row(Row_t{"Korean", "안녕하세요"});

// Enable multi-byte support
table.column(1).format().multi_byte_characters(true);

Right-to-Left Scripts

table.add_row(Row_t{"Arabic", "مرحبا بالعالم"});
table.add_row(Row_t{"Hebrew", "שלום עולם"});

// Enable multi-byte support
table.column(1).format().multi_byte_characters(true);

Complex Scripts

table.add_row(Row_t{"Hindi", "नमस्ते दुनिया"});
table.add_row(Row_t{"Thai", "สวัสดีชาวโลก"});
table.add_row(Row_t{"Bengali", "ওহে বিশ্ব"});

// Enable multi-byte support
table.column(1).format().multi_byte_characters(true);

Special Symbols

// Runic characters
table.add_row(Row_t{"Runic", "ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ"});

// Mathematical symbols
table.add_row(Row_t{"Math", "∑ ∫ ∂ ∇ √ ∞ ≈ ≠ ≤ ≥"});

// Emoji
table.add_row(Row_t{"Emoji", "🔥 💯 ✨ 🚀 ❤️ 👍 🎉"});
All columns containing multi-byte characters must have multi_byte_characters(true) set to ensure proper alignment.

Advanced Unicode Examples

Mixed Content

You can mix ASCII and Unicode in the same table:
Table mixed;
mixed.add_row(Row_t{"Item", "Symbol", "Description"});
mixed.add_row(Row_t{"Check", "✓", "Task completed"});
mixed.add_row(Row_t{"Cross", "✗", "Task failed"});
mixed.add_row(Row_t{"Warning", "⚠", "Attention required"});
mixed.add_row(Row_t{"Star", "★", "Featured item"});

// Only the Symbol column needs multi-byte support
mixed.column(1).format().multi_byte_characters(true);

Box Drawing Characters

Create custom table styles with Unicode box-drawing characters:
Table box;
box.format()
    .corner("╔")
    .border_top("═")
    .border_bottom("═")
    .border_left("║")
    .border_right("║");

box.add_row(Row_t{"Fancy", "Border", "Style"});

Colored Unicode

Combine colors with Unicode characters:
table.add_row(Row_t{"Fire", "🔥🔥🔥"});
table[table.size() - 1][1]
    .format()
    .multi_byte_characters(true)
    .font_color(Color::red)
    .font_style({FontStyle::bold});

Best Practices

Always Enable Multi-Byte Support

For any column that might contain Unicode:
// Apply to specific columns
table.column(1).format().multi_byte_characters(true);

// Or apply to entire table
table.format().multi_byte_characters(true);

Test with Actual Data

Unicode rendering can vary by terminal and font:
Test your tables in the actual environment where they’ll be displayed. Some terminals have better Unicode support than others.

Consider Font Support

Not all fonts include all Unicode characters:
// Stick to common Unicode ranges for maximum compatibility
// Most terminals support:
// - Latin Extended
// - Greek and Coptic
// - Cyrillic
// - CJK (Chinese, Japanese, Korean)
// - Arabic
// - Common symbols and emoji

Troubleshooting

Misaligned Columns

If columns appear misaligned with Unicode text:
// Solution: Enable multi-byte character support
table.column(1).format().multi_byte_characters(true);

Missing Characters

If you see squares or question marks:
  • Check that your terminal supports the character set
  • Verify your terminal’s encoding is set to UTF-8
  • Try a different font with better Unicode coverage

Width Calculation Issues

For emoji or wide characters:
// Some emoji are double-width
table.column(1).format()
    .multi_byte_characters(true)
    .width(30);  // Adjust width as needed

Build docs developers (and LLMs) love