You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang程序写入CSV文件时首条输入重复打印问题求助

Go语言CSV写入首条记录重复问题修复

问题现象

你编写的Go程序可将输入的CSV字符串写入文件,但首条记录会被重复写入。例如当n=2,输入两条记录:

abcd, efgh, ijklmn
opq, rstu, vwxyz

生成的input.csv内容却为:

"abcd, efgh, ijklmn"
"abcd, efgh, ijklmn"
"opq, rstu, vwxyz"

问题原因

核心错误是在循环内部调用csvwriter.WriteAll(lines):

  • 第一次循环时,lines仅包含第一条记录,调用WriteAll会将这条记录写入文件;
  • 第二次循环时,lines追加了第二条记录,此时调用WriteAll会把lines中的所有记录(第一条+第二条)再次写入文件;
  • 最终文件中会出现两次第一条记录,加上第二次写入的第二条,总共三条内容。

另外存在两个潜在问题:

  1. fmt.Scanln(&n)读取数字后,输入缓冲区会遗留换行符,导致第一次scanner.Scan()可能读到空字符串;
  2. 未处理scanner.Scan()的错误,也未用defer确保文件和writer的正确关闭。

修复后的代码

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	n := 0

	inputFile, err := os.Create("input.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer inputFile.Close() // 用defer确保文件关闭

	csvwriter := csv.NewWriter(inputFile)
	defer csvwriter.Flush() // 用defer确保writer刷新缓冲区

	fmt.Println("How many records ?")
	fmt.Scanln(&n)
	// 吃掉Scanln留下的换行符,避免第一次scanner.Scan()读空
	scanner.Scan()

	fmt.Println("Enter the records")
	var lines [][]string
	for i := 0; i < n; i++ {
		if !scanner.Scan() {
			break // 处理输入提前结束的情况
		}
		text := scanner.Text()
		lines = append(lines, []string{text})
	}

	// 检查scanner的错误
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	// 循环结束后一次性写入所有记录
	if err := csvwriter.WriteAll(lines); err != nil {
		log.Fatal(err)
	}
}

修复说明

  1. 将csvwriter.WriteAll(lines)移出循环,收集完所有记录后一次性写入,避免重复写入已有内容;
  2. 添加defer inputFile.Close()和defer csvwriter.Flush(),确保程序退出时资源被正确释放;
  3. 在fmt.Scanln(&n)后调用一次scanner.Scan(),清除遗留的换行符,避免第一条记录读空;
  4. 添加scanner.Err()检查,处理输入过程中可能出现的错误。

验证结果

当输入n=2并输入两条记录后,input.csv的内容为正确的两条:

"abcd, efgh, ijklmn"
"opq, rstu, vwxyz"

内容的提问来源于stack exchange,提问作者HestiaCranel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:45:35