
本文详解如何在go中安全、高效地逐行读取含整数的文本文件,解决因换行符残留导致 `strconv.atoi` 解析失败的常见问题,并推荐使用 `bufio.scanner` 替代 `readstring`。
在Go中逐行读取整数文本文件时,一个典型误区是直接使用 bufio.Reader.ReadString('\n')——该方法会将换行符 \n(或 \r\n)一并包含在返回字符串中。例如,文件中写有 10 后跟换行,ReadString('\n') 实际返回的是 "10\n"(长度为3,若含回车则为4),而非干净的 "10"。这正是你观察到 len(lineStr) == 4 且 strconv.Atoi("10\n") 返回 0 的根本原因:Atoi 和 ParseUint 均要求输入为纯数字字符串,遇到尾部空白或控制字符即解析失败。
✅ 正确做法是使用 bufio.Scanner,它专为按行读取设计,默认以 \n 为分隔符,且自动去除行尾换行符,返回纯净的 string:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
file, err := os.Open("numbers.txt")
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text() // ✅ 自动去除 \n,line = "10", not "10\n"
if num, err := strconv.Atoi(line); err == nil {
fmt.Printf("Parsed: %s → %d\n", line, num)
} else {
fmt.Printf("Failed to parse '%s': %v\n", line, err)
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
}⚠️ 注意事项:
- 永远检查错误:scanner.Err() 应在循环后显式调用,捕获扫描过程中的 I/O 错误;
- 空行与空白处理:若文件可能含空行或首尾空格,建议先 strings.TrimSpace(line) 再解析;
- 大文件性能:Scanner 默认缓冲区为64KB,对超大文件可调用 scanner.Buffer(make([]byte, 64*1024), 1
- 替代方案(需手动清理):若坚持用 ReadString,务必用 strings.TrimSuffix(line, "\n") 或 strings.TrimSpace(line) 清理后再解析。
总结:bufio.Scanner 是Go标准库中读取文本行的首选工具——语义清晰、开箱即用、自动处理换行边界。避免手动处理分隔符带来的隐式污染,让整数解析回归简洁与健壮。
立即学习“go语言免费学习笔记(深入)”;










