Csv 陷入恐慌:行尾的额外分隔符

Csv 陷入恐慌:行尾的额外分隔符,csv,go,Csv,Go,我正在使用Go读取城市位置CSV文件: csvFile, err := os.Open("/path/GeoLiteCity_20130702/GeoLiteCity-Location.csv") defer csvFile.Close() if err != nil { panic(err) } csvf := csv.NewReader(csvFile) csvf.Read() // skip header row for { fields, err := c

我正在使用Go读取城市位置CSV文件:

csvFile, err := os.Open("/path/GeoLiteCity_20130702/GeoLiteCity-Location.csv")
defer csvFile.Close()

if err != nil {
    panic(err)
}

csvf := csv.NewReader(csvFile)
csvf.Read()     // skip header row


for {
    fields, err := csvf.Read()

    if err == io.EOF {
        break
    } else if err != nil {
        panic(err)
    }

    // does nothing yet
}
我得到的错误是:

死机:第2行,第22列:行末尾的额外分隔符

goroutine1[正在运行]:main.main() /path/myprogram.go:239 +0x108f

goroutine 2[可运行]:退出状态2

文件很长,但以以下行开头:

locId,country,region,city,postalCode,latitude,longitude,metroCode,areaCode
1,O1,,,,0.0000,0.0000,,
2,AP,,,,35.0000,105.0000,,
3,EU,,,,47.0000,8.0000,,
4,AD,,,,42.5000,1.5000,,
5,AE,,,,24.0000,54.0000,,
6,AF,,,,33.0000,65.0000,,
7,AG,,,,17.0500,-61.8000,,
8,AI,,,,18.2500,-63.1667,,
9,AL,,,,41.0000,20.0000,,
它似乎格式正确。每行有9个字段

第239行是调用panic的行,
panic(err)
。如您所见,CSV文件的第2行失败,这发生在循环的第一次迭代中(在循环之前读取第1行,以跳过标题行)。第2行的第22列是倒数第二个逗号

我是不是遗漏了什么?我没有看到任何尾随逗号。。。(说明:每行末尾的逗号必须表示空字段值,因此它们不是尾随的,如extra)


更新:

每行甚至有两个尾随逗号

尝试设置
csv.Reader.TrailingComma=true

package main

import (
    "bytes"
    "encoding/csv"
    "fmt"
    "io"
)

var csvData = `locId,country,region,city,postalCode,latitude,longitude,metroCode,areaCode
1,O1,,,,0.0000,0.0000,,
2,AP,,,,35.0000,105.0000,,
3,EU,,,,47.0000,8.0000,,
4,AD,,,,42.5000,1.5000,,
5,AE,,,,24.0000,54.0000,,
6,AF,,,,33.0000,65.0000,,
7,AG,,,,17.0500,-61.8000,,
8,AI,,,,18.2500,-63.1667,,
9,AL,,,,41.0000,20.0000,,
`

func main() {
    csvFile := bytes.NewBufferString(csvData)
    csvf := csv.NewReader(csvFile)
    csvf.TrailingComma = true
    csvf.Read() // skip header row

    for {
        fields, err := csvf.Read()

        if err == io.EOF {
            break
        } else if err != nil {
            panic(err)
        }

        // does nothing yet
        fmt.Println(fields)
    }
}
它通常有助于查看源代码或至少是包文档:-)

以下是一个示例。键为
csvf.TrailingComma=true

package main

import (
    "bytes"
    "encoding/csv"
    "fmt"
    "io"
)

var csvData = `locId,country,region,city,postalCode,latitude,longitude,metroCode,areaCode
1,O1,,,,0.0000,0.0000,,
2,AP,,,,35.0000,105.0000,,
3,EU,,,,47.0000,8.0000,,
4,AD,,,,42.5000,1.5000,,
5,AE,,,,24.0000,54.0000,,
6,AF,,,,33.0000,65.0000,,
7,AG,,,,17.0500,-61.8000,,
8,AI,,,,18.2500,-63.1667,,
9,AL,,,,41.0000,20.0000,,
`

func main() {
    csvFile := bytes.NewBufferString(csvData)
    csvf := csv.NewReader(csvFile)
    csvf.TrailingComma = true
    csvf.Read() // skip header row

    for {
        fields, err := csvf.Read()

        if err == io.EOF {
            break
        } else if err != nil {
            panic(err)
        }

        // does nothing yet
        fmt.Println(fields)
    }
}

当我不移动时,我会试试。但这些不是尾随或额外的逗号,它们确实属于,否则字段计数将是错误的;那些字段肯定是空的,这样就可以了。古怪的我从未见过CSV阅读器默认不接受空的最后字段。这有点令人失望。我同意模块默认拒绝尾随逗号是很奇怪的。这可能是对RFC 4180中以下内容的误解:“记录中的最后一个字段后面不能跟逗号。”我认为这只是表明逗号是字段分隔符,而不是字段分隔符。很难理解他们为什么选择默认拒绝完全正常的CSV文件。看起来Go开发团队也有点被这个问题难住了,并做出了修复:谢谢。古怪的我从未见过CSV阅读器默认不接受空的最后字段。这有点令人失望。