Read lines from text file in go, with bufio.reader

huangapple go评论98阅读模式
英文:

Read lines from text file in go, with bufio.reader

问题

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)
}

我的文本文件由三列和n行组成。第一次调用nextNum时,将返回第一行和第一列中的数字,下一次将返回第二列和第一行中的数字,依此类推。我的问题是当我到达最后一次调用nextNum时,我将收到一个EOF错误,并且最后一行将永远不会被打印出来,因为在此之前会调用break。有关如何解决这个问题的建议吗?

谢谢。

英文:
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)
}

My text file consists of three coloumns and n rows. The first time nextNum is called the number in the first row and first column will be returned, next time the number in the second column and first row, and so on. My problem is when i get to the end and i call nextNum for the last time then i will recieve an EOF error and the last line will never get printed out, becuase break will be called before. Any suggestions on how to solve the problem?

CHeers

答案1

得分: 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)
}

希望对你有帮助!

英文:

I guess there is no new line in the last row in your file and it's simply ending with EOF. It his correct? As a result, the very last column is not being parsed correctly, as it doesn't end with an expected character (\n).

You didn't show us exactly how you're using bufio.Reader, but either way you will need to account for missing new line at the end of file (it's up to you whether treat it as an error or not). Using methods like bufio.Reader.ReadString with \n delimiter won't treat EOF as the end-of-line automatically, but will return you a valid content along with EOF (i.e. you can get both data and error at the same call – note this is a different behaviour than in bufio.Reader.Read).

Saying this, it might be beneficial for you to use the csv package instead. It will solve the EOF problem and you could also benefit from some nicer error messages on unexpected number of columns. The additional features like comments or quotes might be good or bad for your purposes.

Example:

// 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)
}	

答案2

得分: 0

bufio文档中可以看到:

> 在EOF时,计数将为零,err将为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)

不过,你真的应该对错误进行处理,而不仅仅忽略它。

英文:

From the bufio docs:

> At EOF, the count will be zero and err will be io.EOF

So you can simply test for that. Like change your if err != nil to if err != nil && err != io.EOF

or

if err == io.EOF {
    fmt.Println(v, w, cost)
    break
}
if err != nil {
    break
}
fmt.Println(v, w, cost)

Though you really should do something with the error and not just ignore it.

huangapple
  • 本文由 发表于 2015年4月27日 03:01:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/29882117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定