csv 如何解决Golang文件路径.walkfunc问题?

iqih9akk  于 2023-01-28  发布在  Go
关注(0)|答案(1)|浏览(107)

我正在尝试解决一个任务,我必须在名称相似、大小相同的文件中找到一个CSV格式的文件,并在第5行第3列(索引4和2)打印一个数字,因此我编写了以下代码

package main

import (
    "encoding/csv"
    "fmt"
    "os"
    "path/filepath"
)

var s [][]string

func walkfunc(path string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }

    buf, err1 := os.Open(path)
    if err1 == nil {
        var err2 error
        r := csv.NewReader(buf)
        s, err2 = r.ReadAll()
        if err2 == nil {
            fmt.Printf("found: %v", s[4][2])
        }
    }
    defer buf.Close()
    return nil
}
func main() {
    const root = "./task/"
    if err := filepath.Walk(root, walkfunc); err != nil {
        fmt.Printf("error: %v", err)
    }
}

我在输出中得到了这个

GOROOT=/usr/local/go #gosetup
GOPATH=/usr/local/go/bin #gosetup
/usr/local/go/bin/go build -o /private/var/folders/j2/ybr0drz13yq31dc67zmvkb1w0000gn/T/GoLand/___go_build_qwasd3_go /Users/user/Downloads/zadacha/qwasd3.go #gosetup
/private/var/folders/j2/ybr0drz13yq31dc67zmvkb1w0000gn/T/GoLand/___go_build_qwasd3_go
panic: runtime error: index out of range [4] with length 3

goroutine 1 [running]:
main.walkfunc({0x14000018120?, 0x0?}, {0x14000098d88?, 0x10247fe40?}, {0x0?, 0x0?})
        /Users/user/Downloads/zadacha/qwasd3.go:23 +0x28c
path/filepath.walk({0x14000018120, 0xe}, {0x1024c9cf8, 0x140000685b0}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:433 +0xd0
path/filepath.walk({0x10248d4a8, 0x7}, {0x1024c9cf8, 0x140000684e0}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:457 +0x1fc
path/filepath.Walk({0x10248d4a8, 0x7}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:520 +0x6c
main.main()
        /Users/user/Downloads/zadacha/qwasd3.go:37 +0x30

Process finished with the exit code 2

我哪里做错了?
我试图在MacBook上运行此代码。所需的文件包含数字表,我需要在第5行和第3列打印一个数字。

3j86kqsm

3j86kqsm1#

正如其他评论所指出的,你需要检查每一个CSV文件,以确保它实际上和你期望的一样大。你也可以添加一个简单的检查,在打开它之前,通过寻找一个". csv"扩展名来尝试并确保它是一个CSV文件。
不过,要直接解决您的错误... CSV阅读器可能会将纯文本文件解释为CSV,而不会返回错误,例如:

buf := strings.NewReader(`A regular text file with 3 lines.
Line2
Line3
`)

r := csv.NewReader(buf)
records, err := r.ReadAll()

if err != nil {
    fmt.Println("could not read all of CSV file!")
    return err
}

fmt.Println(records)

印刷品:

[[A regular text file with 3 lines.] [Line2] [Line3]]

假设它是一个具有正确行数和列数的CSV文件:

fmt.Println("found", records[4][2])

给出了您共享的紧急消息:

panic: runtime error: index out of range [4] with length 3

您至少需要检查您的CSV是否有5行,如果有,则在尝试读取该 * 字段 * 之前检查第5行是否有3列:

if len(records) < 5 {
    fmt.Println(path, "does not have 5 rows")
    return nil
}

if len(records[4]) < 3 {
    fmt.Println(path, "5th row does not have 3 columns")
    return nil
}

fmt.Println("found", records[4][2])

你也可以在walkfunc中对文件路径本身做一个基本的检查,看看它是否看起来像CSV:

if strings.ToLower(path[len(path)-4:]) != ".csv" {
    fmt.Println(path, "is not a CSV")
    return nil
}

我展示了所有这些代码,以及一个完整的/集成的示例in this Playground

相关问题