
fmt.Scanln 会截断首空格后的输入,导致 strings.Split 实际处理的字符串过短而引发索引越界;应改用 bufio.Scanner 完整读取一行,再安全分割。
`fmt.scanln` 会截断首空格后的输入,导致 `strings.split` 实际处理的字符串过短而引发索引越界;应改用 `bufio.scanner` 完整读取一行,再安全分割。
在 Go 中,fmt.Scanln 的行为常被误解:它按空白符(空格、制表符、换行符)分隔输入,并仅读取第一个字段,随后丢弃该行剩余内容。因此,当用户输入 "2 3" 时,fmt.Scanln(&in) 仅将 "2" 赋值给 in,wh = strings.Split(in, " ") 得到的是 []string{"2"} —— 长度仅为 1,访问 wh[1] 必然触发 panic: index out of range。
✅ 正确做法是使用 bufio.Scanner 完整读取一整行(包括空格),再进行分割:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
var seedCost float64
var lawnNo int
var in string
var area float64
var wh []string
scanner := bufio.NewScanner(os.Stdin)
// 读取 seedCost
scanner.Scan()
seedCost, _ = strconv.ParseFloat(scanner.Text(), 64)
// 读取 lawnNo
scanner.Scan()
lawnNo, _ = strconv.Atoi(scanner.Text())
lawnCost := 0.00
for i := 0; i <p>? 关键要点总结: </p>
-
fmt.Scanln≠ “读一行”,而是“读下一个空白分隔的字段”,不适用于含空格的原始行输入; -
bufio.Scanner是标准、高效、推荐的逐行读取方式,自动处理换行、缓冲和 UTF-8; - 始终对
strings.Split结果做长度校验(len(wh) >= N),避免运行时 panic; - 使用
strconv解析时务必检查错误,而非忽略_(生产代码中应妥善处理错误)。
通过切换输入方式并增加基础校验,即可稳定支持 "2 3"、"10.5 7.2" 等多字段输入场景。










