[c#] Inserting a tab character into text using C#

I'm building an application where I should capture several values and build a text with them: Name, Age, etc.

The output will be a plain text into a TextBox.

I am trying to make those information appear in kind of columns, therefore I am trying to separate them with tab to make it clearer.

For example, instead of having:

Ann 26
Sarah 29
Paul 45

I would like it to show as:

Ann tab 26 Sarah tab 29 Paul tab 45

Any tip on how to insert the tabs into my text?

This question is related to c# .net

The answer is


Try using the \t character in your strings


string St = String.Format("{0,-20} {1,5:N1}\r", names[ctr], hours[ctr]);
richTextBox1.Text += St;

This works well, but you must have a mono-spaced font.


When using literal strings (start with @") this might be easier

char tab = '\u0009';
string A = "Apple";
string B = "Bob";
string myStr = String.Format(@"{0}:{1}{2}", A, tab, B);

Would result in Apple:<tab>Bob


Hazar is right with his \t. Here's the full list of escape characters for C#:

\' for a single quote.

\" for a double quote.

\\ for a backslash.

\0 for a null character.

\a for an alert character.

\b for a backspace.

\f for a form feed.

\n for a new line.

\r for a carriage return.

\t for a horizontal tab.

\v for a vertical tab.

\uxxxx for a unicode character hex value (e.g. \u0020).

\x is the same as \u, but you don't need leading zeroes (e.g. \x20).

\Uxxxxxxxx for a unicode character hex value (longer form needed for generating surrogates).


There are several ways to do it. The simplest is using \t in your text. However, it's possible that \t doesn't work in some situations, like PdfReport nuget package.


It can also be useful to use String.Format, e.g.

String.Format("{0}\t{1}", FirstName,Count);

Using Microsoft Winform controls, it is impossible to solve correctly your problem without an little workaround that I will explain below.

PROBLEM

The problem in using simply "\t" or vbTab is that when more than one TextBox are displayed and that alignment must be respected for all TextBox, the ONLY "\t" or vbTab solution will display something that is NOT ALWAYS correctly aligned.

Example in VB.Net:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    TextBox1.Text = "Bernard" + vbTab + "32"
    TextBox2.Text = "Luc" + vbTab + "47"
    TextBox3.Text = "François-Victor" + vbTab + "12"
End Sub

will display

enter image description here

as you can see, age value for François-Victor is shifted to the right and is not aligned with age value of two others TextBox.

SOLUTION

To solve this problem, you must set Tabs position using a specific SendMessage() user32.dll API function as shown below.

Public Class Form1

    Public Declare Function SendMessage _
        Lib "user32" Alias "SendMessageA" _
        ( ByVal hWnd As IntPtr _
        , ByVal wMsg As Integer _
        , ByVal wParam As Integer _
        , ByVal lParam() As Integer _
        ) As Integer

    Private Const EM_SETTABSTOPS As Integer = &HCB

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim tabs() As Integer = {4 * 25}

        TextBox1.Text = "Bernard" + vbTab + "32"
        SendMessage(TextBox1.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox2.Text = "Luc" + vbTab + "47"
        SendMessage(TextBox2.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox3.Text = "François-Victor" + vbTab + "12"
        SendMessage(TextBox3.Handle, EM_SETTABSTOPS, 1, tabs)
    End Sub

End Class

and following Form will be displayed

enter image description here

You can see that now, all value are correctly aligned :-)

REMARKS

Multiline property of the TextBox must be set to True. If this properties is set to False, the Tab is positioned as before.

How AcceptsTab property is assigned is not important (I have tested).

This question has already be treated on StackOverflow

Caution: the mesure Unit for Tab position is not character but something that seems to be 1/4 of character. That is why I multiply the length by 4.

C# SOLUTION

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam);
        private const int EM_SETTABSTOPS = 0x00CB;
        private const char vbTab = '\t';

        public Form1()
        {
            InitializeComponent();

            var tabs = new uint[] { 25 * 4 };

            textBox1.Text = "Bernard" + vbTab + "32";
            SendMessage(textBox1.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox2.Text = "Luc" + vbTab + "47";
            SendMessage(textBox2.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox3.Text = "François-Victor" + vbTab + "12";
            SendMessage(textBox3.Handle, EM_SETTABSTOPS, 1, tabs);
        }
    }
}

var text = "Ann@26"

var editedText = text.Replace("@", "\t");

It can also be useful to use String.Format, e.g.

String.Format("{0}\t{1}", FirstName,Count);

Using Microsoft Winform controls, it is impossible to solve correctly your problem without an little workaround that I will explain below.

PROBLEM

The problem in using simply "\t" or vbTab is that when more than one TextBox are displayed and that alignment must be respected for all TextBox, the ONLY "\t" or vbTab solution will display something that is NOT ALWAYS correctly aligned.

Example in VB.Net:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    TextBox1.Text = "Bernard" + vbTab + "32"
    TextBox2.Text = "Luc" + vbTab + "47"
    TextBox3.Text = "François-Victor" + vbTab + "12"
End Sub

will display

enter image description here

as you can see, age value for François-Victor is shifted to the right and is not aligned with age value of two others TextBox.

SOLUTION

To solve this problem, you must set Tabs position using a specific SendMessage() user32.dll API function as shown below.

Public Class Form1

    Public Declare Function SendMessage _
        Lib "user32" Alias "SendMessageA" _
        ( ByVal hWnd As IntPtr _
        , ByVal wMsg As Integer _
        , ByVal wParam As Integer _
        , ByVal lParam() As Integer _
        ) As Integer

    Private Const EM_SETTABSTOPS As Integer = &HCB

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim tabs() As Integer = {4 * 25}

        TextBox1.Text = "Bernard" + vbTab + "32"
        SendMessage(TextBox1.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox2.Text = "Luc" + vbTab + "47"
        SendMessage(TextBox2.Handle, EM_SETTABSTOPS, 1, tabs)
        TextBox3.Text = "François-Victor" + vbTab + "12"
        SendMessage(TextBox3.Handle, EM_SETTABSTOPS, 1, tabs)
    End Sub

End Class

and following Form will be displayed

enter image description here

You can see that now, all value are correctly aligned :-)

REMARKS

Multiline property of the TextBox must be set to True. If this properties is set to False, the Tab is positioned as before.

How AcceptsTab property is assigned is not important (I have tested).

This question has already be treated on StackOverflow

Caution: the mesure Unit for Tab position is not character but something that seems to be 1/4 of character. That is why I multiply the length by 4.

C# SOLUTION

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam);
        private const int EM_SETTABSTOPS = 0x00CB;
        private const char vbTab = '\t';

        public Form1()
        {
            InitializeComponent();

            var tabs = new uint[] { 25 * 4 };

            textBox1.Text = "Bernard" + vbTab + "32";
            SendMessage(textBox1.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox2.Text = "Luc" + vbTab + "47";
            SendMessage(textBox2.Handle, EM_SETTABSTOPS, 1, tabs);
            textBox3.Text = "François-Victor" + vbTab + "12";
            SendMessage(textBox3.Handle, EM_SETTABSTOPS, 1, tabs);
        }
    }
}

There are several ways to do it. The simplest is using \t in your text. However, it's possible that \t doesn't work in some situations, like PdfReport nuget package.


In addition to the anwsers above you can use PadLeft or PadRight:

string name = "John";
string surname = "Smith";

Console.WriteLine("Name:".PadRight(15)+"Surname:".PadRight(15));
Console.WriteLine( name.PadRight(15) + surname.PadRight(15));

This will fill in the string with spaces to the left or right.


Hazar is right with his \t. Here's the full list of escape characters for C#:

\' for a single quote.

\" for a double quote.

\\ for a backslash.

\0 for a null character.

\a for an alert character.

\b for a backspace.

\f for a form feed.

\n for a new line.

\r for a carriage return.

\t for a horizontal tab.

\v for a vertical tab.

\uxxxx for a unicode character hex value (e.g. \u0020).

\x is the same as \u, but you don't need leading zeroes (e.g. \x20).

\Uxxxxxxxx for a unicode character hex value (longer form needed for generating surrogates).


When using literal strings (start with @") this might be easier

char tab = '\u0009';
string A = "Apple";
string B = "Bob";
string myStr = String.Format(@"{0}:{1}{2}", A, tab, B);

Would result in Apple:<tab>Bob


It can also be useful to use String.Format, e.g.

String.Format("{0}\t{1}", FirstName,Count);

var text = "Ann@26"

var editedText = text.Replace("@", "\t");

string St = String.Format("{0,-20} {1,5:N1}\r", names[ctr], hours[ctr]);
richTextBox1.Text += St;

This works well, but you must have a mono-spaced font.


Hazar is right with his \t. Here's the full list of escape characters for C#:

\' for a single quote.

\" for a double quote.

\\ for a backslash.

\0 for a null character.

\a for an alert character.

\b for a backspace.

\f for a form feed.

\n for a new line.

\r for a carriage return.

\t for a horizontal tab.

\v for a vertical tab.

\uxxxx for a unicode character hex value (e.g. \u0020).

\x is the same as \u, but you don't need leading zeroes (e.g. \x20).

\Uxxxxxxxx for a unicode character hex value (longer form needed for generating surrogates).


It can also be useful to use String.Format, e.g.

String.Format("{0}\t{1}", FirstName,Count);

Hazar is right with his \t. Here's the full list of escape characters for C#:

\' for a single quote.

\" for a double quote.

\\ for a backslash.

\0 for a null character.

\a for an alert character.

\b for a backspace.

\f for a form feed.

\n for a new line.

\r for a carriage return.

\t for a horizontal tab.

\v for a vertical tab.

\uxxxx for a unicode character hex value (e.g. \u0020).

\x is the same as \u, but you don't need leading zeroes (e.g. \x20).

\Uxxxxxxxx for a unicode character hex value (longer form needed for generating surrogates).