fmt包中提供了3类读取输入的函数:

  • Scan家族:从标准输入os.Stdin中读取数据,包括Scan()、Scanf()、Scanln()
  • SScan家族:从字符串中读取数据,包括Sscan()、Sscanf()、Sscanln()
  • Fscan家族:从io.Reader中读取数据,包括Fscan()、Fscanf()、Fscanln()

其中:

  • Scanln、Sscanln、Fscanln在遇到换行符的时候停止
  • Scan、Sscan、Fscan将换行符当作空格处理
  • Scanf、Sscanf、Fscanf根据给定的format格式读取,就像Printf一样

这3家族的函数都返回读取的记录数量,并会设置报错信息,例如读取的记录数量不足、超出或者类型转换失败等。

以下是它们的定义方式:

  1. $ go doc fmt | grep -Ei "func [FS]*Scan"
  2. func Fscan(r io.Reader, a ...interface{}) (n int, err error)
  3. func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
  4. func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
  5. func Scan(a ...interface{}) (n int, err error)
  6. func Scanf(format string, a ...interface{}) (n int, err error)
  7. func Scanln(a ...interface{}) (n int, err error)
  8. func Sscan(str string, a ...interface{}) (n int, err error)
  9. func Sscanf(str string, format string, a ...interface{}) (n int, err error)
  10. func Sscanln(str string, a ...interface{}) (n int, err error)

因为还没介绍io.Reader,所以Fscan家族的函数暂且略过,但用法和另外两家族的scan类函数是一样的。

Scan、Scanf和Scanln

Scan家族函数从标准输入读取数据时,将以空格为分隔符分隔标准输入中的内容,并将分隔后的各个记录保存到给定的变量中。其中Scanf()可以指定分隔符。

例如,使用Scanln函数等待用户输入数据,或从管道中读取数据。下面的代码将等待用户输入,且将读取的内容分别保存到name变量和age变量中:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var (
  7. name string
  8. age int
  9. )
  10. fmt.Print("输入姓名和年龄,使用空格分隔:")
  11. fmt.Scanln(&name, &age)
  12. fmt.Printf("name: %s\nage: %d\n", name, age)
  13. }

因为Scanln()遇到换行符或EOF的时候终止读取,所以在输入的时候只要按下回车键就会结束读取。

运行它,将提示输入姓名:

  1. 请输入姓名和年龄,空格分隔:
  2. 周伯通 69
  3. name: 周伯通
  4. age: 69

同理Scanf()也在遇到换行符或EOF的时候终止读取行为。使用Scanf()的时候,需要给定格式化字符串形式:

例如:

  1. fmt.Scanf("%s %d",&name,&age)

输入时,第一个字段会转换成字符串格式保存到name变量中,第二个记录会转换成整数保存到age中,如果转换失败,将不会进行保存。例如输入malongshuai aaa,由于aaa无法转换成int,所以age变量的值仍然为初始化的数值0。

Scanf可指定分隔符,其中上面的是%s %d中间的空格就是分隔符。例如下面指定:作为分隔符:

  1. fmt.Scanf("%s : %d",&name,&age)

在输入时,必须按照以下格式进行输入:首先至少一个空格,然后一个冒号,再至少一个空格:

  1. 周伯通 : 23 // 或者连续多个空格 "周伯通 : 23"
  2. name: 周伯通
  3. age: 23

如果使用的是fmt.Scan(),则输入数据时可以换行输入,Scan()会将换行符作为空格进行处理,直到读取到了2个记录之后自动终止读取操作:

  1. fmt.Scan(&name, &age)
  2. 请输入姓名和年龄,空格分隔:周伯通
  3. 87
  4. name: 周伯通
  5. age: 87

一般来说,只使用Scanf类函数比较好。

返回值

这些函数都有返回值:读取的记录数量和err信息。

以Scanln()为例:

  1. func main() {
  2. var (
  3. name string
  4. age int
  5. )
  6. fmt.Print("输入姓名和年龄,使用空格分隔:")
  7. n, err := fmt.Scanln(&name, &age)
  8. fmt.Printf("name: %s\nage: %d\n", name, age)
  9. fmt.Println("records count:",n)
  10. fmt.Println("err or not:",err)
  11. }

输入:

  1. malongshuai 23 // n = 2, err = nil
  2. malongshuai // n = 1, err != nil
  3. malongshuai long // n = 2, err != nil
  4. malongshuai 23 23 // n = 2, err != nil

Sscan、Sscanf和Scanln

Sscan家族的函数用于从给定字符串中读取数据,用法和Scan家族类似。

  1. func Sscan(str string, a ...interface{}) (n int, err error)
  2. func Sscanln(str string, a ...interface{}) (n int, err error)
  3. func Sscanf(str string, format string, a ...interface{}) (n int, err error)

例如:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var (
  7. name string
  8. age int
  9. )
  10. input := "malongshuai 23"
  11. fmt.Sscan(input, &name, &age)
  12. fmt.Printf("name: %s\nage: %d\n", name, age)
  13. }

使用Sscanf()可以指定分隔符:

  1. input := "malongshuai : 23"
  2. fmt.Sscanf(input, "%s : %d", &name, &age)

使用bufio中读取标准输入

除了fmt包的Scan类函数,bufio包也可以读取标准输入。当然,读取标准输入只是它的一个功能示例,它的作用是操作缓冲IO。

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. )
  7. var inputReader *bufio.Reader
  8. var input string
  9. var err error
  10. func main() {
  11. inputReader = bufio.NewReader(os.Stdin)
  12. fmt.Println("输入姓名:")
  13. input, err = inputReader.ReadString('\n')
  14. if err == nil {
  15. fmt.Printf("The input was: %s\n", input)
  16. }
  17. }

其中NewReader()创建一个bufio.Reader实例,表示创建一个从给定文件中读取数据的读取器对象。然后调用读取器对象(Reader实例)的ReadString()方法,这个方法以\n作为分隔符,它的分隔符必须只能是单字符,且必须使用单引号包围,因为它会作为byte读取。ReadString()读取来自os.Stdin的内容后将其保存到input变量中,同时返回是否出错的信息。ReadString()只有一种情况会返回err:没有遇到分隔符。

ReadString会将读取的内容包括分隔符都一起放进缓冲中,如果读取文件时读到了结尾,则会将整个文件内容放进缓冲,并将文件终止标识符io.EOF放进设置为err。

通常无需单独定义这些变量,下面是更常见的用法。

  1. inputReader := bufio.NewReader(os.Stdin)
  2. input, err := inputReader.ReadString('\n')

Go基础系列:读取标准输入的更多相关文章

  1. SQL Server-字字珠玑,一纸详文,完全理解SERIALIZABLE最高隔离级别(基础系列收尾篇)

    前言 对于上述锁其实是一个老生常谈的话题了,但是我们是否能够很明确的知道在什么情况下会存在上述各种锁类型呢,本节作为SQL Server系列末篇我们 来详细讲解下. Range-Lock 上述关于Ra ...

  2. 你所不知道的ASP.NET Core MVC/WebApi基础系列(一)

    前言 最近发表的EF Core貌似有点多,可别误以为我只专攻EF Core哦,私下有时间也是一直在看ASP.NET Core的内容,所以后续会穿插讲EF Core和ASP.NET Core,别认为你会 ...

  3. JVM基础系列第7讲:JVM 类加载机制

    当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...

  4. JVM基础系列第3讲:到底什么是虚拟机?

    我们都知道在 Windows 系统上一个软件包装包是 exe 后缀的,而这个软件包在苹果的 Mac OSX 系统上是无法安装的.类似地,Mac OSX 系统上软件安装包则是 dmg 后缀,同样无法在 ...

  5. SpringBoot基础系列-SpringBoot配置

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9990680.html SpringBoot基础系列-SpringBoot配置 概述 属性 ...

  6. mybatis基础系列(二)——基础语法、别名、输入映射、输出映射

    增删改查 mapper根节点及其子节点 mybatis框架需要读取映射文件创建会话工厂,映射文件是以<mapper>作为根节点,在根节点中支持9个元素,分别为insert.update.d ...

  7. mybatis基础系列(一)——mybatis入门

    好久不发博客了,写博文的一个好处是能让心静下来,整理下之前学习过的一些知识一起分享,大神路过~ mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. ...

  8. c#基础系列3---深入理解ref 和out

    "大菜":源于自己刚踏入猿途混沌时起,自我感觉不是一般的菜,因而得名"大菜",于自身共勉. 扩展阅读 c#基础系列1---深入理解 值类型和引用类型 c#基础系 ...

  9. 你所不知道的ASP.NET Core MVC/WebApi基础系列 (一)

    转自博客:https://www.cnblogs.com/CreateMyself/p/9235968.html 前言 最近发表的EF Core貌似有点多,可别误以为我只专攻EF Core哦,私下有时 ...

随机推荐

  1. bower学习总结

    1. 安装软件:node-v6.10.3-x64.msi 和 Git-2.13.0-64-bit.exe 在安装git时,需要选择‘Run Git from the Windows Command P ...

  2. java(一) 基础部分

    1.11.简单讲一下java的跨平台原理 Java通过不同的系统.不同版本.不同位数的java虚拟机(jvm),来屏蔽不同的系统指令集差异而对外体统统一的接口(java API),对于我们普通的jav ...

  3. Python环境安装及IDE介绍

    因为最近时间比较松散,公司的业务也不多,所以想趁机赶紧投入到人工智能的学习大业当中.经过多次比较,看到目前市面上还是使用Python做为基础语言较多,进儿学习算法.人工智能组件.机器学习.数据挖掘等课 ...

  4. 前端 高级 (二十五)vue2.0项目实战一 配置简要说明、代码简要说明、Import/Export、轮播和列表例子

    一.启动服务自动打开浏览器运行 二.配置简要说明 1.node_modules 安装好的依赖文件,中间件等,所在位置 2.package.jason 配置当前项目要安装的中间件和依赖文件 { &quo ...

  5. c# 使用资源文件

    1.新建项目 2.新建资源文件 3. 代码中使用嵌入资源 using System;using System.Collections.Generic;using System.Text;using S ...

  6. 12、json、GridView、缓存

    1.解析json数据: public class PhotosData { public int retcode; public PhotosInfo data; public class Photo ...

  7. 遇到ANR问题的处理步骤

    遇到ANR问题的处理步骤 问题描述 开发中难免会遇到ANR的问题,遇到ANR问题不要想着是因为设备的卡顿出现的问题,我们无法解决,我们应先找到导致ANR的原因,分析原因之后,再来判断这个问题可不可以解 ...

  8. springboot tomcat配置参数列表

    springboot tomcat的配置选项大全 server. Port = xxxx server. Address = server. contextPath = server. display ...

  9. 简单粗暴的JavaScript笔记-1

    欢迎到我的简书查看我的文集 前言: 提示密码提示框 <head> <style> #div1 {width: 100px;height:50px;background:#FFC ...

  10. JavaScript百宝箱

    Js的外部引用 外部文件中不用添加<script>标签,引用书写位置需在使用之前 <script type="text/javascript" src=" ...