If you would like your strings in Go to be printed in aligned columns, it’s essential to add the padding, i.e., filling the string with whitespace characters at the start or finish in order that the output has a set variety of characters. To do that, you should utilize particular flags, like "%-10s"
, added to format “verbs” when formatting textual content. You can even use an exterior bundle or the built-in textual content/tabwriter
to print the info in aligned columns.
Print a string with padding utilizing fmt
Utilizing the built-in fmt.Printf()
operate, you possibly can set the format of the printed information utilizing so-called verbs reminiscent of "%s"
. Furthermore, there are a number of flags to enhance the show of strings. One in every of them is the flag so as to add padding, which is the quantity specifying its measurement within the verb "%s"
, between "%"
and "s"
. By default, the string is padded with areas on the left (the textual content is right-justified). If you would like proper padding and left alignment, add the -
flag earlier than the padding measurement.
Examples:
format | description |
---|---|
"%s" |
Customary string format |
"%20s" |
Pad string with the areas on the left (right-justified string) |
"%-20s" |
Pad string with the areas on the appropriate (left-justified string) |
Left padding instance
// left padding
fmt.Printf("+%s+n", strings.Repeat("-", 45))
fmt.Printf("| %20s | %20s |n", "greens", "fruits")
fmt.Printf("|%s|n", strings.Repeat("-", 45))
fmt.Printf("| %20s | %20s |n", "potato", "strawberry")
fmt.Printf("+%s+n", strings.Repeat("-", 45))
Output:
+---------------------------------------------+
| greens | fruits |
|---------------------------------------------|
| potato | strawberry |
+---------------------------------------------+
Proper padding instance
// proper padding
fmt.Printf("+%s+n", strings.Repeat("-", 45))
fmt.Printf("| %-20s | %-20s |n", "greens", "fruits")
fmt.Printf("|%s|n", strings.Repeat("-", 45))
fmt.Printf("| %-20s | %-20s |n", "potato", "strawberry")
fmt.Printf("+%s+n", strings.Repeat("-", 45))
Output:
+---------------------------------------------+
| greens | fruits |
|---------------------------------------------|
| potato | strawberry |
+---------------------------------------------+
Variable padding measurement
However what if we wish to print a big desk with columns of various widths, whose measurement would adapt to the size of the strings? On this case, the padding measurement might be variable, however that isn’t an issue for the fmt.Printf()
operate. The instance beneath exhibits how to do that.
bundle important
import (
"fmt"
"strings"
)
func printTable(desk [][]string) {
// get variety of columns from the primary desk row
columnLengths := make([]int, len(desk[0]))
for _, line := vary desk {
for i, val := vary line {
if len(val) > columnLengths[i] {
columnLengths[i] = len(val)
}
}
}
var lineLength int
for _, c := vary columnLengths %s "
lineLength += 1 // +1 for the final "|" within the line
for i, line := vary desk {
if i == 0 { // desk header
fmt.Printf("+%s+n", strings.Repeat("-", lineLength-2)) // lineLength-2 due to "+" as first and final character
}
for j, val := vary line %-*s ", columnLengths[j], val)
if j == len(line)-1 n")
if i == 0 || i == len(desk)-1 { // desk header or final line
fmt.Printf("+%s+n", strings.Repeat("-", lineLength-2)) // lineLength-2 due to "+" as first and final character
}
}
}
func important() {
var desk = [][]string{
{"greens", "fruits", "rank"},
{"potato", "strawberry", "1"},
{"lettuce", "raspberry", "2"},
{"carrot", "apple", "3"},
{"broccoli", "pomegranate", "4"},
}
printTable(desk)
}
Output:
+---------------------------------+
| greens | fruits | rank |
+---------------------------------+
| potato | strawberry | 1 |
| lettuce | raspberry | 2 |
| carrot | apple | 3 |
| broccoli | pomegranate | 4 |
+---------------------------------+
Many of the code is used to calculate the variety of characters to print, and you should have no bother understanding it when you fastidiously observe it. What pursuits us essentially the most is the road:
fmt.Printf("| %-*s ", columnLengths[j], val)
An asterisk *
within the format specifies that the padding measurement must be given as an argument to the fmt.Printf()
operate. On this case, the padding is columnLengths[j]
.
Rearrange the arguments
It is usually potential to rearrange the arguments within the format string. The instance beneath exhibits that by including numeric values in sq. brackets in entrance of the formatting placeholders, we are able to management the order by which every argument happens.
fmt.Printf("| %-[2]*[1]s ", val, columnLengths[j])
The [n]
notation is very helpful if we’ve got repeating values within the string format. In such a state of affairs they’ll solely be given as an argument as soon as:
fmt.Printf("I am a %[1]s, an awesome %[1]sn", "programmer")
Summarized examples with the variable measurement padding:
format | description |
---|---|
"%s" |
Customary string format |
"%*s" |
Pad string with a variable variety of areas on the left (right-justified string) |
"%-*s" |
Pad string with a variable variety of areas on the appropriate (left-justified string) |
"%-[2]*[1]s" |
As above however the first argument is the string, and the second, the padding measurement |
Print textual content in aligned columns utilizing textual content/tabwriter
The Go commonplace library additionally features a helpful textual content/tabwriter
bundle that creates correctly aligned tables from strings separated by t
characters. Such a formatting is especially helpful for creating command-line purposes that print tabular information. Within the instance beneath, we initialize tabwriter.Author
by setting output to the usual output os.Stdout
, t
because the padding character and 4
because the width of the tab character. For printing, the road cells must be concatenated right into a single string separated by tabs. We do that utilizing the strings.Be a part of()
operate. The tabwriter.Author
requires each column cell to be tab-terminated, so we additionally add the t
for the final cell within the row.
bundle important
import (
"fmt"
"os"
"strings"
"textual content/tabwriter"
)
func printTable(desk [][]string) {
author := tabwriter.NewWriter(os.Stdout, 0, 4, 0, 't', 0)
for _, line := vary desk {
fmt.Fprintln(author, strings.Be a part of(line, "t")+"t")
}
author.Flush()
}
func important() {
var desk = [][]string{
{"greens", "fruits", "rank"},
{"potato", "strawberry", "1"},
{"lettuce", "raspberry", "2"},
{"carrot", "apple", "3"},
{"broccoli", "pomegranate", "4"},
}
printTable(desk)
}
Output:
greens fruits rank
potato strawberry 1
lettuce raspberry 2
carrot apple 3
broccoli pomegranate 4