go语言中输入:Scan,Scanln和Scanf的应运与区别
-
输入:让用户输入数据,实现交互,我们在学习其他语言的时候就有类似的操作如Java中的Scanner,那么go语言中的输入是什么,下面就带大家看一看go语言中输入的语句是什么。
-
在go语言中我们可以通过fmt包中的这些方法来实现输入操作
- fmt.Scan
- fmt.Scanln
- fmt.Scanf
-
看到三个有的同学就开始懵了,这三个都有输入的功能是不是都一样,想啥呢。如果都一样怎么可能在这里介绍哈,这里就介绍一下他们三个的运用与区别。
Scan:
1.1简单使用:
- 可以输入一个,也阔以同时输入多个值,下面有说。
//声明一个要输入的变量
var name string
fmt.Print("请输入用户名:")
//使用Scan来实现输入操作,记得括号中的变量名前面要加一个寻址符,相当于name的内存地址。Scan实现在它的内存空间中赋值,此时name的值就是我们输入的值。
fmt.Scan(&name)
fmt.Printf(name)
1.2Scan的返回值
- 在使用Scan的时候,用户输入完成之后,会返回两个值
- count:用户输入了几个值
- err: 用户输入错误,提示错误信息
- 当输入多个值的时候,记得使用空格分开输入,
- 如果不想使用某一个返回值可以使用 _ 来接收,如果两个都不想要,只是单纯的输入,那就直接写等号后面的即可。
- 特别说明:fmt.Scan 要求 如果要输入两个值,必须输入两个,如果是三个值,就必须是三个。否则他会一直等待,不会执行下面的程序。
var name string
var age int
// 当使用Scan时,会提示用户输入
fmt.Println("请输入用户名:")
//当我们输入的时候,一定要和自己定义的数量,类型一样,否则就会发生错误
count, err := fmt.Scan(&name, &age)
if err == nil {
fmt.Println(name, age)
} else {
fmt.Println("用户输入数据个数", count //返回用户输入数据的个数
fmt.Println("用户输入数据错误", err) //返回错误,默认是nil
}
Scanln
- 我们阔以发现,
Scan
和Scanln
长的十分的像,其实上面讲的Scan的功能效果和Scanln一模一样,但他们中有一个不同点。- fmt.Scan 要求 如果要输入两个值,必须输入两个,如果是三个值,就必须是三个。否则他会一直等待,不会执行下面的程序。
- fmt.Scanln 没有这个强制的要求,如果要求我们输入两个值,但是我们只输入一个值,我们回车之后就阔以直接执行程序,但是会报错,我们可以判断返回值err,会报错值为输入。这就是他们两个的不同。
- 总结:
Scan
必须等待所要求的值输入完成才能执行程序,但是Scanln
不管输入的数据是否完成,只要回车就直接执行。
package main
import "fmt"
func main() {
// 示例1:fmt.Scanln
/*
var name string
fmt.Print("请输入用户名:")
fmt.Scanln(&name)
fmt.Printf(name)
*/
// 示例2:fmt.Scanln
var name string
var age int
fmt.Print("请输入用户名:")
// 当使用Scanln时,会提示用户输入
// 用户输入完成之后,会得到两个值:count,用户输入了几个值;err,用输入错误则是错误信息
count, err := fmt.Scanln(&name, &age)
fmt.Println(count, err)
fmt.Println(name, age)
// 特别说明:fmt.Scanln 等待回车。
}
Scanf
- Scanf规定用户在输入的时候除了输入相关的&+变量还要在前面加上“%相关类型”
func main() {
var name string
fmt.Print("请输入用户名:")
fmt.Scanf("%s", &name)
fmt.Println(name, age)
}
//如果输入多个,类似输入即可,比如两个
var name string
var age int
fmt.Print("请输入用户名:")
fmt.Scanf("%s,%d ", &name, &age)
fmt.Println(name, age)
-
它也有两个返回值count和err,上面讲了,这里就不再赘叙了
-
如果在Scanf中写了两个输入值但是只输入一个,那样未输入的值就是该值类型的默认值。
-
支持用户定制化输入
- 注意⚠️:
- 我们在输入的时候必须加上引号中的模版,如例子中输入的话必须是 :我叫 alex 今年 19 岁,然后会输入 alex 和 19两个值
- 如例子中,我们在输入的时候按照模版输入,要输入的元素的前面的模版元素类型一样的时候要使用空格隔开,否则系统会误以为,后面的数据都是压迫输入的
- 在输入时,一定要按照模版的格式来写,模版有空格码输入的时候也要有,否则出错。
- 注意⚠️:
-
我们按照格式输入,但是没有加空格
- 我们加上空格
- 当输入的内容类型和模版类型一样时就要用空格,为了方便,建议大家不管什么情况都加空格,以免出现问题。
func main() {
var name string
var age int
fmt.Print("请输入用户名:")
_, _ = fmt.Scanf("我叫%s 今年%d 岁", &name, &age)
fmt.Println(name, age)
}
空格问题(在输入的时候,想要连同空格输入)
- 我们在输入的时候,肯定遇到过这样的情况,我们想输入一行带有空格的数据,但是输入要求,一旦空格就代表一个输入值的结束,那我们该如何连同空格一起输入?
- 使用os.Stdin:相当于一个文件,我们把输入的东西放在里面,最后一下读取。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// line,从stdin中读取一行的数据(字节集合 -> 转化成为字符串)
// reader默认一次能4096个字节(4096/3)
// 1. 一次性读完,isPrefix=false
// 2. 先读一部分,isPrefix=true,再去读取isPrefix=false
line, _, _ := reader.ReadLine()
data := string(line)
fmt.Println(data)
}
可以使用上述这种方法来实现空格的输入。
吐槽:有时候挺喜欢Java中Scanner,特别是解决洛谷中的问题,好多要输入空格,在Java中是需要这样做即可,哈哈哈,就是吐槽一下,go语言的语法真的十分简便,随着发展,可能会解决这个问题。
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();