我需要从数据库中的数据创建一个固定长度的文本文件。数据导出没有问题,将数据加载到Go也可以。如何以固定长度样式打印数据?
我有以下结构
type D struct {
A10 string // Should be 10 characters in result file
A20 string // Should be 20 characters in result file
A50 string // Should be 50 characters in result file
}
var d := D{ "ten", "twenty", "fifty" }
因此,打印结构的结果应为
| ten| twenty| fifty|
我已经发现,fmt.Printf("%10s", "ten")
将会预占到10个前导空格,但我无法弄清楚如何阻止它溢出:fmt.Printf("%10s", "tenaaaaaaaa")
将打印11个字符。
我想到了一个遍历每个领域的功能并切断了很长的字符串:
func trimTooLong(d *D) {
d.A10 = d.A10[:10]
d.A20 = d.A20[:20]
d.A50 = d.A20[:50]
}
会有更好的方法吗?
答案 0 :(得分:3)
您可以使用字符串格式的精度将输出截断为字段宽度。
fmt.Printf("%5.5s", "Hello, world")
fmt.Printf("%5.5s", "A")
将输出"Hello A"
。
所以在你的例子中,这将解决问题:
fmt.Printf("%10.10s%20.20s%50.50s", d.A10, d.A20, d.A50)
答案 1 :(得分:0)
我认为你的方法很好。您还可以使用TextMarhsaler
或Stringer
界面比使用函数更干净地完成此操作。
答案 2 :(得分:0)
你的方法确实很好,但IMO你应该用那段代码重新思考你的目标。
在没有TextMarshaler或String的情况下实现它的一种简洁方法是使用类似的东西:
func writeTrimmed(w io.Writer, in []*D) error {
for _, d := range in {
a10, a20, a50 := d.A10, d.A20, d.A50
if len(a10) > 10 {
a10 = a10[:10]
}
if len(a20) > 20 {
a20 = a20[:20]
}
if len(a50) > 50 {
a50 = a50[:50]
}
if _, err := fmt.Fprintf(w, "|%10s|%20s|%50s|\n", a10, a20, a50); err != nil {
return err
}
}
return nil
}