Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to dynamically pass values to Sprintf or Printf

Tags:

printf

go

If I want to pad a string I could use something like this:

https://play.golang.org/p/ATeUhSP18N

package main

import (
    "fmt"
)

func main() {
    x := fmt.Sprintf("%+20s", "Hello World!")
    fmt.Println(x)
}

From https://golang.org/pkg/fmt/

 +  always print a sign for numeric values; 
    guarantee ASCII-only output for %q (%+q)
 -  pad with spaces on the right rather than the left (left-justify the field)

But If I would like to dynamically change the pad size how could I pass the value ?

My first guest was:

x := fmt.Sprintf("%+%ds", 20, "Hello World!")

But I get this:

%ds%!(EXTRA int=20, string=Hello World!)

Is there a way of doing this without creating a custom pad function what would add spaces either left or right probably using a for loop:

for i := 0; i < n; i++ {
    out += str
}
like image 826
nbari Avatar asked Feb 17 '17 21:02

nbari


2 Answers

Use * to tell Sprintf to get a formatting parameter from the argument list:

fmt.Printf("%*s\n", 20, "Hello World!")

Full code on play.golang.org

like image 187
dolmen Avatar answered Sep 19 '22 20:09

dolmen


Go to: https://golang.org/pkg/fmt/ and scroll down until you find this:

fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6)

equivalent to

fmt.Sprintf("%6.2f", 12.0)

will yield " 12.00". Because an explicit index affects subsequent verbs, this notation can be used to print the same values multiple times by resetting the index for the first argument to be repeated

This sounds like what you want.

The real core of the description of using arguments to set field width and precision occurs further above:

Width and precision are measured in units of Unicode code points, that is, runes. (This differs from C's printf where the units are always measured in bytes.) Either or both of the flags may be replaced with the character '*', causing their values to be obtained from the next operand, which must be of type int.

The example above is just using explicit indexing into the argument list in addition, which is sometimes nice to have and allows you to reuse the same width and precision values for more conversions.

So you could also write:

    fmt.Sprintf("*.*f", 6, 2, 12.0)
like image 40
Thomas Kammeyer Avatar answered Sep 19 '22 20:09

Thomas Kammeyer