for {
v, err = nextNum(reader, ' ')
if err != nil {
break
}
w, err = nextNum(reader, ' ')
if err != nil {
break
}
cost, err = nextNum(reader, '\n')
if err != nil {
break
}
fmt.Println(v, w, cost)
}
我的文本文件由三个coloumns和n行组成。第一次调用nextNum时第一行中的数字和第一列将被返回,下一次是第二列和第一行中的数字,依此类推。我的问题是当我到达终点并且我最后一次调用nextNum然后我将收到一个EOF错误并且最后一行将永远不会打印出来,因为之前会调用break。有关如何解决问题的任何建议吗?
干杯
答案 0 :(得分:1)
我猜您文件的最后一行没有新行,而只是以EOF
结尾。这是他的正确吗?因此,最后一列未正确解析,因为它不以预期字符(\n
)结束。
您没有准确地向我们展示您使用bufio.Reader
的确切方式,但无论哪种方式,您都需要考虑文件末尾缺少的新行(无论是将其视为错误还是不)。使用bufio.Reader.ReadString
和\n
分隔符等方法不会自动将EOF
视为行尾,但会返回有效内容和EOF
(即您可以在同一个调用中同时获取数据和错误 - 请注意,这与bufio.Reader.Read
)中的行为不同。
说到这一点,使用csv
包可能对您有利。它将解决EOF
问题,您还可以从意外数量的列上获得一些更好的错误消息。评论或引用等附加功能可能对您的目的有利或不利。
// No line break at the end, pure EOF (still works)
data := "one 1\ntwo 2\nthree 3\nfour 4"
// You can wrap your file reader with bufio.Reader here
cr := csv.NewReader(bytes.NewReader([]byte(data)))
cr.Comma = ' '
cr.FieldsPerRecord = 2
var err error
for err == nil {
var columns []string
if columns, err = cr.Read(); err == nil {
fmt.Println(columns)
// err = processRow(columns)
}
}
if err != io.EOF {
// Parse error
panic(err)
}
答案 1 :(得分:0)
来自bufio docs:
在EOF,计数将为零,错误将为io.EOF
所以你可以简单地测试一下。比如将if err != nil
更改为if err != nil && err != io.EOF
或
if err == io.EOF {
fmt.Println(v, w, cost)
break
}
if err != nil {
break
}
fmt.Println(v, w, cost)
虽然你真的应该对错误做点什么而不是忽略它。