Go语言中三个输入函数(scanf,scan,scanln)的区别解析

 更新时间:2024年10月29日 14:58:54   作者:2301_76723322  
本文详细介绍了Go语言中三个输入函数Scanf、Scan和Scanln的区别,包括用法、功能和输入终止条件等,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

Go语言中三个输入函数(scanf,scan,scanln)的区别

在 Go 语言中,fmt 包提供了三种输入函数:Scanf、Scan 和 Scanln。这三个函数都是用于从标准输入读取数据并存储到变量中,但是它们在处理输入的方式上有所不同。下面详细解读每个函数的特点和用法。

1. fmt.Scanf

  • 用法:fmt.Scanf(format string, a …interface{}) (n int, err error)
  • 功能:根据格式化字符串 format 从标准输入读取数据,并将数据存储到提供的参数中。格式化字符串类似于 C 语言中的 scanf,例如 %d 表示读取一个整数,%s 表示读取一个字符串。
  • 输入终止条件:Scanf 读取输入时,会忽略空白字符,并且根据格式化字符串解析输入内容。输入可以包含换行符,但解析会按照格式字符串中的要求进行。

示例代码:

package main
import (
    "fmt"
)
func main() {
    var a int
    var b string
    fmt.Print("请输入一个整数和一个字符串(格式如:123 hello):")
    fmt.Scanf("%d %s", &a, &b) // 根据格式化字符串读取
    fmt.Println("整数:", a)
    fmt.Println("字符串:", b)
}

注意:

如果输入的格式与指定的格式字符串不匹配,可能会导致读取失败或产生意外结果。

2. fmt.Scan

  • 用法:fmt.Scan(a …interface{}) (n int, err error)
  • 功能:读取由空格分隔的输入数据,并将数据存储到提供的参数中。它不需要格式化字符串,而是依次将输入的值赋给传入的变量。
  • 输入终止条件:输入以空格或换行符为分隔符,读取的值必须与传入的参数数量匹配。

示例代码:

package main
import (
    "fmt"
)
func main() {
    var a int
    var b string
    fmt.Print("请输入一个整数和一个字符串(用空格分隔):")
    fmt.Scan(&a, &b) // 直接读取输入到变量中
    fmt.Println("整数:", a)
    fmt.Println("字符串:", b)
}

注意:

  • 输入数据必须能正确解析为指定的变量类型,否则会出现错误。
  • 如果输入的值数量与变量数量不匹配,程序会等待进一步的输入。

3. fmt.Scanln

  • 用法:fmt.Scanln(a …interface{}) (n int, err error)
  • 功能:与 fmt.Scan 类似,但会在读取完所有指定的参数后检查是否有多余的输入。它要求读取的最后一个输入参数必须位于行的末尾,否则会返回一个错误。
  • 输入终止条件:读取到换行符结束,并要求读取的参数数量与传入的变量数量匹配。

示例代码:

package main
import (
    "fmt"
)
func main() {
    var a int
    var b string
    fmt.Print("请输入一个整数和一个字符串(用空格分隔,并按回车结束):")
    fmt.Scanln(&a, &b) // 读取输入到变量中,并检查换行
    fmt.Println("整数:", a)
    fmt.Println("字符串:", b)
}

注意: 如果输入的值数量与传入的变量数量不匹配,或者在读取所有参数后还有多余的输入,则会返回错误。 总结比较

在这里插入图片描述

  • Scanf 更加灵活,可以指定格式,但要求输入格式必须匹配。
  • Scan 和 Scanln 更适合简单的输入读取,Scanln 还会检查是否有多余的输入。
    在实际应用中,根据需要选择适当的函数来读取用户输入。

这三种函数,都会将换行符,一起读取吗?

在 Go 语言中,fmt.Scanf、fmt.Scan 和 fmt.Scanln 这三个函数处理换行符的方式有所不同。让我们详细解释它们对换行符的处理:

1. fmt.Scanf

  • 换行符处理:Scanf 不会将换行符视为特殊的输入结束标记,它会根据指定的格式化字符串来解析输入数据。
  • 输入中包含换行符:如果换行符符合格式化字符串的要求,它会被视为空白字符而被忽略,否则会被保留在输入流中等待下一次读取

示例:

var a int
var b string
fmt.Print("请输入一个整数和一个字符串(如:123 hello):")
fmt.Scanf("%d %s", &a, &b) // 如果输入 "123\nhello",换行符会被忽略

在这个例子中,输入时如果用户输入 “123\nhello”,换行符会被忽略,因为它只是分隔了两个数据。

2. fmt.Scan

  • 换行符处理:Scan 将换行符视为空白字符,与空格一样被忽略。它会继续读取输入,直到满足所有变量的赋值。
  • 连续输入的情况:即使输入中有换行符,Scan 仍然会尝试从输入流中读取更多的数据,直到满足要求的变量数量。

示例:

var a int
var b string
fmt.Print("请输入一个整数和一个字符串(用空格分隔):")
fmt.Scan(&a, &b) // 如果输入 "123\nhello",换行符会被忽略

在这个例子中,输入 “123\nhello” 时,Scan 会忽略换行符并继续读取输入,直到读取到字符串 “hello”。

3. fmt.Scanln

  • 换行符处理:Scanln 会将换行符作为输入的结束标志。当所有的输入参数都读取完毕后,Scanln 要求输入流中不能有多余的数据。如果有多余的数据,即使是换行符,也会返回错误。
  • 换行符终止:它要求最后一个输入参数之后必须是换行符,否则会报错。

示例:

var a int
var b string
fmt.Print("请输入一个整数和一个字符串(用空格分隔,并按回车结束):")
fmt.Scanln(&a, &b) // 如果输入 "123 hello\n",换行符作为结束标志

在这个例子中,输入 “123 hello\n” 时,Scanln 会正常读取到整数和字符串,并认为换行符是输入的结束标志。

总结

  • Scanf:根据格式化字符串解析输入,换行符如果不影响解析会被忽略。
  • Scan:将换行符视为空白字符,会继续读取更多数据,直到满足所有变量的赋值要求。
  • Scanln:以换行符作为输入结束标志,如果在所有参数读取完毕后还有多余输入(除了换行符),会返回错误。

换行符是否被读取取决于函数的设计和用法,Scanln 是唯一一个明确要求换行符作为结束标志的函数。

输入中包含换行符:如果换行符符合格式化字符串的要求,它会被视为空白字符而被忽略,否则会被保留在输入流中等待下一次读取。
对上面加粗部分的解释:
为了更好地理解 fmt.Scanf 如何处理输入中的换行符,下面举一个具体的例子来说明这种行为。

例子

package main
import (
    "fmt"
)
func main() {
    var a int
    var b string
    fmt.Print("请输入一个整数和一个字符串(格式:123 hello):")
    fmt.Scanf("%d %s", &a, &b)
    fmt.Println("a:", a)
    fmt.Println("b:", b)
}

示例 1:

  • 输入内容:123 hello,然后按下 Enter(实际上输入的是 “123 hello\n”)。
  • 执行过程:

a.fmt.Scanf(“%d %s”, &a, &b) 尝试按格式化字符串 %d %s 解析输入数据。
b.%d 匹配到整数部分,读取 123,成功解析并赋值给变量 a。
c.%s 匹配到字符串部分,读取 hello,成功解析并赋值给变量 b。
d.剩余的换行符 \n 被 Scanf 视为分隔符(空白字符)而忽略掉。

结果: 输出:

a: 123
b: hello

示例 2:输入 “123\nhello”

  • 输入内容:123,按下 Enter 键(输入 “123\n”),然后再输入 hello 并按下 Enter。
  • 执行过程:

a.fmt.Scanf(“%d %s”, &a, &b) 首先尝试解析 %d,从输入 “123\n” 中读取到整数 123 并赋值给 a。
b.接下来,fmt.Scanf 尝试读取 %s,但此时输入流中的字符是换行符 \n,它不符合字符串的格式要求。因此,Scanf 读取 %s 的尝试失败,换行符 \n 被保留在输入流中等待下一次读取。
c.因为读取 %s 失败,b 没有被赋值,程序继续等待下一个输入。
d.当用户再输入 hello 并按下 Enter 后,Scanf 成功读取到字符串 hello 并赋值给 b。

结果: 输出:

a: 123
b: hello

解释

在示例 1 中,“123 hello\n” 中的换行符被视为空白字符,符合格式化字符串的要求,因此被忽略。而在示例 2 中,“123\nhello” 中的换行符不符合 %s 的格式要求,导致 Scanf 读取失败,换行符保留在输入流中,等待下一次读取。
这展示了 fmt.Scanf 处理换行符的两种情况:符合格式时忽略,不符合时保留在输入流中。

到此这篇关于Go语言中三个输入函数(scanf,scan,scanln)的区别的文章就介绍到这了,更多相关Go 输入函数scanf,scan,scanln内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解Golang中占位符的使用

    深入了解Golang中占位符的使用

    在写 golang 的时候,也是有对应的格式控制符,也叫做占位符,写这个占位符,需要有对应的数据与之对应,不能瞎搞。本文就来和大家聊聊Golang中占位符的使用,希望对大家有所帮助
    2023-03-03
  • go mod tidy拉取依赖包bug问题及解决

    go mod tidy拉取依赖包bug问题及解决

    这篇文章主要介绍了go mod tidy拉取依赖包bug问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • golang实现微信小程序商城后台系统(moshopserver)

    golang实现微信小程序商城后台系统(moshopserver)

    这篇文章主要介绍了golang实现微信小程序商城后台系统(moshopserver),本文通过截图实例代码的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • GIN的路由以及传参问题

    GIN的路由以及传参问题

    本文主要介绍了GIN的路由以及传参问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • GO语言结构体面向对象操作示例

    GO语言结构体面向对象操作示例

    这篇文章主要介绍了GO语言编程中结构体面向对象的操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go中gin框架的*gin.Context参数常见实用方法

    Go中gin框架的*gin.Context参数常见实用方法

    *gin.Context是处理HTTP请求的核心,ctx代表"context"(上下文),它包含了处理请求所需的所有信息和方法,例如请求数据、响应构建器、路由参数等,这篇文章主要介绍了Go中gin框架的*gin.Context参数常见实用方法,需要的朋友可以参考下
    2024-07-07
  • Go可变参数函数的实现

    Go可变参数函数的实现

    可变参数函数是指函数参数的某个参数可有可无,即这个参数的个数可以为0会多个,可变参数函数参数在日常编程中大量使用,本文主要介绍了Go可变参数函数的实现,感兴趣的可以了解一下
    2023-12-12
  • go实现base64编码的四种方式

    go实现base64编码的四种方式

    本文主要介绍了go实现base64编码的四种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • golang对自定义类型进行排序的解决方法

    golang对自定义类型进行排序的解决方法

    学习一门编程语言,要掌握原子数据类型,还需要掌握自定义数据类型。下面这篇文章主要给大家介绍了关于golang如何对自定义类型进行排序的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • golang修改结构体中的切片值方法

    golang修改结构体中的切片值方法

    这篇文章主要介绍了golang修改结构体中的切片值方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论