Golang中Scan和Scanln的区别是什么
Golang中Scan和Scanln的区别是什么 我是一名刚开始学习Go语言的学生。这是我今天遇到的一个问题。
import "fmt"
func main() {
var key string
loop := true
balance := 10000.0
money := 0.0
note := ""
details := "收支\t账户金额\t收支金额\t说明"
for {
fmt.Println("\n--------------------家庭收支记账软件-------------------")
fmt.Println(" 1 details")
fmt.Println(" 2 input")
fmt.Println(" 3 withdraw")
fmt.Println(" 4 exit")
fmt.Println()
fmt.Println(" please choice(1-4):")
fmt.Scanln(&key)
switch key {
case "1":
fmt.Println("--------------------details-------------------")
fmt.Println(details)
case "2":
fmt.Println("input for this time:")
fmt.Scan(&money)
fmt.Println("note for this time:")
fmt.Scan(¬e)
balance += money
details += fmt.Sprintf("\ninput\t%v\t%v\t%v", balance, money, note)
case "3":
fmt.Println("登记支出...")
case "4":
loop = false
default:
fmt.Println("it`s not right")
}
if !loop {
break
}
}
fmt.Println("you have exit")
}
这是我的代码。 当它启动时,我输入2,然后输入金额和备注, 然后,它又从2开始循环,就像这样:

但是,如果我使用 Scanln 而不是 Scan(即 fmt.Scanln(&money) 和 fmt.Scanln(¬e)),它就能正常工作。
为什么?
希望有好心人能帮助我。
更多关于Golang中Scan和Scanln的区别是什么的实战教程也可以访问 https://www.itying.com/category-94-b0.html
谢谢!我之前读过 fmt 包的内容,但我还是不明白。我只想输入一个“3”,不要有空格。
更多关于Golang中Scan和Scanln的区别是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于 note 变量没有获取到你输入的所有单词?fmt.Scan 在遇到空格后会停止读取输入(标准输入)。
fmt 包 - fmt - pkg.go.dev
fmt 包实现了格式化 I/O,其函数类似于 C 语言中的 printf 和 scanf。
你可能希望将整行(包括空格)读取到 note 变量中:
fmt 包 - fmt - pkg.go.dev
fmt 包实现了格式化 I/O,其函数类似于 C 语言中的 printf 和 scanf。
你的意思是不想在备注后面换行吗?
你是在循环开始处打印的,把它去掉
for {
// 下面的 Println 中不要打印换行
fmt.Println("--------------------家庭收支记账软件-------------------")
fmt.Println(" 1 收支明细")
fmt.Println(" 2 登记收入")
fmt.Println(" 3 登记支出")
fmt.Println(" 4 退出")
fmt.Println()
fmt.Println(" 请选择(1-4):")
fmt.Scanln(&key)
switch key {
case "1":
fmt.Println("--------------------收支明细-------------------")
fmt.Println(details)
case "2":
fmt.Println("本次收入金额:")
fmt.Scan(&money)
fmt.Println("本次收入说明:")
fmt.Scanln(¬e)
balance += money
details += fmt.Sprintf("\n收入\t%f\t%f\t%s", balance, money, note)
fmt.Printf("备注是:" + "'" +note + "'" + "\n")
在Go语言中,fmt.Scan和fmt.Scanln的主要区别在于它们处理输入缓冲区中换行符的方式。
关键区别:
Scanln:读取输入直到遇到换行符,并丢弃该换行符Scan:读取输入但不会自动丢弃换行符,换行符会留在输入缓冲区中
在你的代码中,当使用fmt.Scan(&money)读取金额后,输入缓冲区中仍然保留着换行符。接着执行fmt.Scan(¬e)时,它会立即遇到这个换行符,将其解释为空输入,导致note变量获取不到值,程序继续执行。
示例代码说明:
package main
import "fmt"
func main() {
// 使用Scan的问题示例
var money float64
var note string
fmt.Print("输入金额: ")
fmt.Scan(&money) // 输入"100"后按回车
fmt.Print("输入备注: ")
fmt.Scan(¬e) // 这里会立即读取到缓冲区中的换行符
fmt.Printf("金额: %v, 备注: '%s'\n", money, note)
// 输出: 金额: 100, 备注: ''
}
// 使用Scanln的正确示例
func exampleWithScanln() {
var money float64
var note string
fmt.Print("输入金额: ")
fmt.Scanln(&money) // 读取"100"并丢弃换行符
fmt.Print("输入备注: ")
fmt.Scanln(¬e) // 可以正常读取用户输入
fmt.Printf("金额: %v, 备注: '%s'\n", money, note)
// 输出: 金额: 100, 备注: '工资'
}
// 如果必须使用Scan,可以添加额外的读取来清除换行符
func exampleWithScanFixed() {
var money float64
var note string
fmt.Print("输入金额: ")
fmt.Scan(&money)
// 清除输入缓冲区中的换行符
var discard string
fmt.Scanln(&discard)
fmt.Print("输入备注: ")
fmt.Scan(¬e)
fmt.Printf("金额: %v, 备注: '%s'\n", money, note)
}
在你的记账软件中,使用Scanln是正确的选择,因为它能正确处理行尾的换行符,确保每次读取都能获取到用户的完整输入。

