
本文介绍使用 `bufio.newreader` 替代 `fmt.scan` 来完整读取含空格的多词字符串,解决 `fmt.scan` 仅截取首个单词的问题,并提供可直接运行的示例代码与关键注意事项。
在 Go 语言中,fmt.Scan(&variable) 默认以空白字符(空格、制表符、换行符)为分隔符,因此它只会读取输入中的第一个单词,后续内容被忽略。若需读取整行(包括空格、标点和多个单词),必须使用更底层的 I/O 方式——bufio.Reader 是标准且推荐的解决方案。
以下是一个完整、健壮的示例程序:
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入一行文本:")
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("读取输入时发生错误:", err)
return
}
// 去除末尾的换行符(\n 或 \r\n)
input = strings.TrimSpace(input)
fmt.Printf("你输入的是:%q\n", input)
}✅ 运行效果示例:
请输入一行文本:Hello, 世界! Go is awesome. 你输入的是:"Hello, 世界! Go is awesome."
? 关键说明:
- reader.ReadString('\n') 会一直读取直到遇到换行符(即用户按下 Enter),完整捕获整行内容;
- 必须调用 strings.TrimSpace(input) 移除末尾的 \n(或 Windows 下的 \r\n),否则打印时会出现多余空行;
- 务必检查 err —— 忽略错误(如用户意外关闭输入流)可能导致程序行为异常,生产环境不可省略;
- fmt.Scanln 虽也能读整行,但会自动裁剪末尾空格且不支持连续空格保留,语义不如 ReadString 明确可控。
? 小贴士:
若需多次读取多行输入,可将 reader 复用;若需解析结构化数据(如空格分隔的字段),可在读取整行后用 strings.Fields() 拆分——它按任意空白字符分割并自动过滤空字符串。
总之,当目标是“读取用户键入的一整行原始文本”时,请始终优先选择 bufio.NewReader(os.Stdin).ReadString('\n'),这是 Go 标准库中清晰、安全、符合直觉的标准做法。










