Golang中csv.NewReader在首条记录前添加空格的问题

Golang中csv.NewReader在首条记录前添加空格的问题 我正在读取一个CSV文件,发现读取的第一条记录开头有一个空格(也可能不是空格,但在控制台中显示为空格)。我找不到任何原因或相关文档提及这个问题。

有人能给我指点一下方向吗?谢谢。

package main

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

func main() {

	// Struct to hold schedule.csv
	type Sched struct {
		schDate  string
		schShift string
	}

	// hardcodings
	filename := "schedule.csv"

	// Open CSV file
	f, err := os.Open(filename)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// Read File into a Variable
	lines, err := csv.NewReader(f).ReadAll()
	if err != nil {
		panic(err)
	}

	// Loop through lines & turn into object
	for _, line := range lines {
		data := Sched{
			schDate:  line[0],
			schShift: line[1],
		}
		if data.schShift == "" {
			break
		}

		fmt.Printf("START:%s\n", data.schDate)
	}
}

更多关于Golang中csv.NewReader在首条记录前添加空格的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

也许这就是全部了 😊 有时候问题不在我的编码 谢谢

更多关于Golang中csv.NewReader在首条记录前添加空格的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我在记事本中打开并重新保存,没有显示任何特殊字符。本以为这样可以清除那些问题,所以我把注意力集中在代码上。我将从头开始创建CSV文件,看看结果如何。

这个问题通常是由于CSV文件包含字节顺序标记(BOM)或文件开头存在不可见字符导致的。csv.NewReader不会自动处理这些字符,因此它们会被包含在第一个字段中。

以下是几种解决方案:

方案1:使用utf8bom包跳过BOM

import (
    "encoding/csv"
    "golang.org/x/text/encoding/unicode"
    "golang.org/x/text/transform"
)

func main() {
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    // 创建UTF-8 BOM感知的reader
    utf8bom := unicode.BOMOverride(unicode.UTF8.NewDecoder())
    reader := transform.NewReader(f, utf8bom)
    
    lines, err := csv.NewReader(reader).ReadAll()
    if err != nil {
        panic(err)
    }
    // ... 其余代码
}

方案2:手动检测并移除BOM

func main() {
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    // 读取文件开头检测BOM
    bom := make([]byte, 3)
    n, err := f.Read(bom)
    if err != nil {
        panic(err)
    }

    // 如果不是UTF-8 BOM,则重置文件指针
    if n < 3 || bom[0] != 0xEF || bom[1] != 0xBB || bom[2] != 0xBF {
        _, err = f.Seek(0, 0)
        if err != nil {
            panic(err)
        }
    }

    lines, err := csv.NewReader(f).ReadAll()
    if err != nil {
        panic(err)
    }
    // ... 其余代码
}

方案3:处理读取后的数据

func main() {
    // ... 文件打开代码

    lines, err := csv.NewReader(f).ReadAll()
    if err != nil {
        panic(err)
    }

    // 处理第一行的BOM
    if len(lines) > 0 && len(lines[0]) > 0 {
        lines[0][0] = strings.TrimSpace(lines[0][0])
    }

    // ... 其余代码
}

方案4:使用strings.TrimSpace清理每个字段

for _, line := range lines {
    data := Sched{
        schDate:  strings.TrimSpace(line[0]),
        schShift: strings.TrimSpace(line[1]),
    }
    if data.schShift == "" {
        break
    }
    fmt.Printf("START:%s\n", data.schDate)
}

最推荐使用方案4,因为它简单且能处理各种空白字符问题。如果确定是BOM导致的,可以使用方案1或2。

回到顶部