gpt4 book ai didi

go - reader.ReadLine() 在 scanner.Scan() 调用后不前进

转载 作者:IT王子 更新时间:2023-10-29 01:39:09 25 4
gpt4 key购买 nike

下面的代码从这个文件中读取它的值:

2 3\n
1.0 2.0 3.0\n
-1.0 -2.0 -3.0\n

并且应该打印:[{1 2 3},{-1 -2 -3}]

但我得到的是:

[{2 [31 2 3]} {0 []}] strconv.ParseFloat:解析“3.0-1.0”:语法无效

reader.ReadLine() 似乎停留在同一位置。有没有更简单的方法来扫描行,然后扫描每行内的值?

package main

import (
"bufio"
"bytes"
"fmt"
"os"
"strconv"
"strings"
)

type Example struct {
classLabel int
attributes []float64
}

func NewExample(classLabel int, attributes []float64) *Example {
return &Example{classLabel, attributes}
}

func readFile(path string) ([]Example, error) {

var (
result []Example
err error
file *os.File
part []byte
size int
attributeNum int
)

if file, err = os.Open(path); err != nil {
return result, err
}
defer file.Close()

reader := bufio.NewReader(file)
buffer := bytes.NewBuffer(make([]byte, 0))

if part, _, err = reader.ReadLine(); err != nil {
return result, err
}
buffer.Write(part)
newLine := buffer.String()
fmt.Println("newLine=" + newLine)

r := strings.NewReader(newLine)
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanWords)

if scanner.Scan() {
size, err = strconv.Atoi(scanner.Text())
if err != nil {
return result, err
}
}
fmt.Println("size=" + strconv.Itoa(size))

if scanner.Scan() {
attributeNum, err = strconv.Atoi(scanner.Text())
if err != nil {
return result, err
}
}
fmt.Println("attributeNum=" + strconv.Itoa(attributeNum))

result = make([]Example, size)

var classLabel int
var attributes []float64

for k := 0; k < size; k++ {
if part, _, err = reader.ReadLine(); err != nil {
return result, err
}
buffer.Write(part)
newLine := buffer.String()
fmt.Println("newLine=" + newLine)

r := strings.NewReader(newLine)
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanWords)

if scanner.Scan() {
classLabel, err = strconv.Atoi(scanner.Text())
if err != nil {
return result, err
}
}
fmt.Println("classLabel=" + strconv.Itoa(classLabel))

for i := 0; i < attributeNum; i++ {
var attribute float64
if scanner.Scan() {
attribute, err = strconv.ParseFloat(scanner.Text(), 64)
if err != nil {
return result, err
}
attributes = append(attributes, attribute)
fmt.Println("attribute=" + strconv.FormatFloat(attribute, 'f', -1, 64))
}
}
result[k] = *NewExample(classLabel, attributes)
}

return result, scanner.Err()
}

func main() {
example, err := readFile("test.txt")
fmt.Println(example, err)
}

最佳答案

当您在 for 循环中执行此操作时:

buffer.Write(part)
newLine := buffer.String()
fmt.Println("newLine=" + newLine)

下一行被附加到buffer。那是,在循环开始之前,buffer 包含 2 3,然后在读取1.0 2.0 3.0之后,它被附加到缓冲区,所以内容变成了2 31.0 2.0 3.0,您将其存储在 newLine 中。这就是事情开始发生变化的地方。

您可能希望在读取每一行之前清除缓冲区:

buffer.Reset()
buffer.Write(part)
newLine := buffer.String()
fmt.Println("newLine=" + newLine)

但是你还会有更多的问题,在这里:

    if scanner.Scan() {
classLabel, err = strconv.Atoi(scanner.Text())
if err != nil {
return result, err
}
}

由于该行包含 1.0 2.0 3.0strconf.Atoi 将失败。我不明白这个片段的目的,也许您可以删除它(或注释掉)。

在解决了上面的问题之后,您仍然会遇到一个问题,在这一行:

          attributes = append(attributes, attribute)

由于 attributes 永远不会重置,因此它会不断增长。也就是说,在第一行之后,它将包含 1 2 3,在第二行之后它将包含 1 2 3 -1 -2 -3。您可以通过在没有外循环的情况下移动 attributes 的声明来更正该问题,如下所示:

    var attributes []float64
for i := 0; i < attributeNum; i++ {
var attribute float64
if scanner.Scan() {
attribute, err = strconv.ParseFloat(scanner.Text(), 64)
if err != nil {
return result, err
}
attributes = append(attributes, attribute)
fmt.Println("attribute=" + strconv.FormatFloat(attribute, 'f', -1, 64))
}
}

关于go - reader.ReadLine() 在 scanner.Scan() 调用后不前进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37205971/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com