Is possible, with fmt.Println("...")
to print a string with center alignement of the shell?

- 20,262
- 30
- 97
- 159
-
1So do you know the width of the shell or is that part of what you need to work out how to do? – miltonb Dec 14 '16 at 02:06
-
This can tell you the width and height: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window – miltonb Dec 14 '16 at 02:53
-
@miltonb, your link is for bash, ... can I use bash from go? – sensorario Dec 14 '16 at 11:08
-
Yes, you can make a call to OS using `os/exec` package. It will take some lines of code based around `exec.Command()`. – miltonb Dec 14 '16 at 19:38
2 Answers
As an update to this long-answered question, the solution posted by @miltonb can be improved upon by using the *
notation from the fmt
package. From the package documentation:
In Printf, Sprintf, and Fprintf, the default behavior is for each formatting verb to format successive arguments passed in the call. However, the notation [n] immediately before the verb indicates that the nth one-indexed argument is to be formatted instead. The same notation before a '*' for a width or precision selects the argument index holding the value. After processing a bracketed expression [n], subsequent verbs will use arguments n+1, n+2, etc. unless otherwise directed.
So you can replace two of the fmt.Sprintf
calls with a more concise format statement to achieve the same result:
s := "in the middle"
w := 110 // or whatever
fmt.Sprintf("%[1]*s", -w, fmt.Sprintf("%[1]*s", (w + len(s))/2, s))
Additionally, as @chris-dennis mentioned, the [1]
notation is superfluous in this example because the width of the string is already the first argument. This works as well:
fmt.Sprintf("%*s", -w, fmt.Sprintf("%*s", (w + len(s))/2, s))

- 4,050
- 18
- 26
-
1Excellent addition regarding the [n] notation, makes it simpler - which is always better. – miltonb Dec 15 '17 at 02:37
-
Good answer, but in fact it works without the `[1]`s, because in each case the width is the first argument. – Chris Dennis Dec 05 '20 at 19:48
This code is managing to centre the text as long as the shell width is a known value. Its not quite 'pixel perfect', but I hope it helps.
If we break it down there are two bits of code to produce the format strings to pad right and then left.
fmt.Sprintf("%%-%ds", w/2) // produces "%-55s" which is pad left string
fmt.Sprintf("%%%ds", w/2) // produces "%55s" which is right pad
So the final Printf
statement becomes
fmt.Printf("%-55s", fmt.Sprintf("%55s", "my string to centre"))
The full code:
s := " in the middle"
w := 110 // shell width
fmt.Printf(fmt.Sprintf("%%-%ds", w/2), fmt.Sprintf(fmt.Sprintf("%%%ds", w/2),s))
Produces the following:
in the middle
Link to play ground: play

- 6,905
- 8
- 45
- 55
-
I've seen. But could you explain a bit "%%-%ds"? Doc says `%% a literal percent sign; consumes no value` what exactly means? `%d is for digit`. – sensorario Dec 14 '16 at 11:21
-
Updated with better description of the code to produce the format strings. – miltonb Dec 14 '16 at 19:33
-
1I think there's a bug in the solution code, as it does not take into account the width of the string `s`. See the modified playground code at https://play.golang.org/p/8L5IfEIKSS. I think you need to replace the first `w/2` with a `w` and the second with a `(w + len(s))/2`, as shown in my answer below. – PaSTE Dec 14 '17 at 23:20