
fmt.Scanln 会以空格和换行符为分隔符截断输入,无法读取含空格的完整字符串;应改用 bufio.NewReader(os.Stdin) 配合 ReadString('\n') 或 ReadLine() 实现真正的“读取一行”。
`fmt.scanln` 会以空格和换行符为分隔符截断输入,无法读取含空格的完整字符串;应改用 `bufio.newreader(os.stdin)` 配合 `readstring('\n')` 或 `readline()` 实现真正的“读取一行”。
在 Go 中,fmt.Scanln 并非“读取一行”,而是按空格/制表符/换行符分割的词扫描器。它遇到第一个空白字符(包括空格、Tab 或换行)即停止,因此输入 "Hello World" 时,只会捕获 "Hello",剩余部分仍滞留在输入缓冲区,导致后续读取异常或被意外跳过。
要真正读取用户输入的完整一行(含空格),必须使用 bufio.Reader。以下是修正后的完整示例:
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// ✅ 正确读取文件名(含空格也不截断)
fmt.Print("请输入文件名(不带扩展名): ")
fileName, err := reader.ReadString('\n')
check(err)
fileName = strings.TrimSpace(fileName) // 去除末尾的 \n 和可能的空格
fullFileName := fileName + ".txt"
fmt.Printf("将创建文件: %s\n", fullFileName)
file, err := os.Create(fullFileName)
check(err)
defer file.Close()
// ✅ 正确读取待写入内容(支持空格、中文、符号等)
fmt.Print("请输入要写入的内容: ")
content, err := reader.ReadString('\n')
check(err)
content = strings.TrimSpace(content)
if len(content) == 0 {
panic("输入内容不能为空")
}
_, err = file.WriteString(content)
check(err)
fmt.Println("✅ 写入成功!")
// 验证读取
data, err := ioutil.ReadFile(fullFileName)
check(err)
fmt.Println("******************* 文件内容 *********************")
fmt.Println(string(data))
}
func check(e error) {
if e != nil {
panic(e)
}
}? 关键说明:
- reader.ReadString('\n') 会一直读取直到遇到换行符(\n),并包含该换行符在返回字符串中,因此务必用 strings.TrimSpace() 清理;
- reader.ReadLine() 是底层方法,返回 []byte 和布尔值(是否因缓冲区满而未读完),更适用于大文本或性能敏感场景,日常推荐 ReadString;
- 切勿混用 fmt.Scanln 与 bufio.Reader —— 它们共享同一输入流,混用会导致读取错位(如第二次读取直接跳过);
- 使用 defer file.Close() 确保文件句柄及时释放,是 Go 的最佳实践。
通过以上方式,即可稳定、可靠地读取任意长度、含空格、标点甚至 Unicode 字符的用户输入,彻底解决“只读到第一个单词”的常见误区。
立即学习“go语言免费学习笔记(深入)”;


















