英文:
How to create a fixed length text file in Golang?
问题
我需要从数据库中的数据创建一个固定长度的文本文件。数据导出没有问题,将数据加载到Go中也可以。如何以固定长度的样式打印数据?
我有以下结构体:
type D struct {
A10 string // 结果文件中应该有10个字符
A20 string // 结果文件中应该有20个字符
A50 string // 结果文件中应该有50个字符
}
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]
}
是否有更好的方法?
英文:
I need to create a fixed length text file from data in a database. The data export is no problem, and loading data into Go also works. How would I print the data in a fixed length style?
I have the following struct
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" }
So, the result of the printed struct should be
| ten| twenty| fifty|
I already figured out, that fmt.Printf("%10s", "ten")
will prepend up until 10 leading spaces, but I couldn't figure out how to stop it from overflowing: fmt.Printf("%10s", "tenaaaaaaaa")
will print 11 characters.
I thought about a function which goes through every field and cuts out too long strings:
func trimTooLong(d *D) {
d.A10 = d.A10[:10]
d.A20 = d.A20[:20]
d.A50 = d.A20[:50]
}
Would there be a better approach?
答案1
得分: 6
你可以使用字符串格式中的精度来截断输出的字段宽度。
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)
英文:
You can use the precision in the string format to truncate the output as the field width.
fmt.Printf("%5.5s", "Hello, world")
fmt.Printf("%5.5s", "A")
will output "Hello A"
.
So in your example, this will do the trick:
fmt.Printf("%10.10s%20.20s%50.50s", d.A10, d.A20, d.A50)
答案2
得分: 0
我认为你的方法很好。你还可以使用TextMarshaler
或Stringer
接口来比使用函数更清晰地完成。
英文:
I think that your method is fine. You could also use the TextMarhsaler
or the Stringer
interface to do it more cleanly than with a function.
答案3
得分: 0
你的方法很好,但是我认为你应该重新考虑一下你的代码目标。
一种更简洁的实现方式是不使用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
}
你可以在playground上查看示例代码。
英文:
Your approach is fine really, but IMO you should rethink your goal with that code.
A clean way to implement it without TextMarshaler or String is using something like:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论