最近开始学习GO语言,并做了一些编程练习。有道题要输入带空格的字符串,这在C/C++中很容易实现,但GO中好像并不那么容易。学过C/C++的可能都知道,在C中可以使用gets()函数,在C++可以使用getline()函数来实现输入带空格的字符串。那我们可能要问在GO中有没有类似的函数?答案是否定的。

在GO中除了fmt和os包,我们还可以使用bufio来实现带缓存输入和输出。

我们要怎样读取用户从键盘(控制台)输入的数据?输入是指从键盘或其它标准输入(os.Stdin)读取数据。

使用fmt包里的Scan_或Sscan_系列函数输入

package main

import "fmt"

var (
firstName, lastName string
str1, str2, str3 string
num int
str = "We / love / Go / 1314"
format = "%s / %s / %s / %d"
) func main() {
fmt.Println("Please input your full name: ")
// 使用Scan输入
fmt.Scan(&firstName, &lastName)
fmt.Printf("Hi %s %s!\n", firstName, lastName) fmt.Println("Please again input your full name: ")
// 使用Scanln输入
fmt.Scanln(&firstName, &lastName)
fmt.Printf("Hi %s %s!\n", firstName, lastName) fmt.Println("Please again input your full name: ") // 使用Scanf输入
fmt.Scanf("%s %s", &firstName, &lastName)
fmt.Printf("Hi %s %s!\n", firstName, lastName) fmt.Println("From the str we read: ") // 使用Sscanf读取
fmt.Sscanf(str, format, &str1, &str2, &str3, &num)
fmt.Println(str1, str2, str3, num)
}

若输入为:

xiao hua
xiao ming
xiao hong

则输出为:

Please input your full name:
xiao hua
Hi xiao hua!
Please again input your full name:
xiao ming
Hi xiao ming!
Please again input your full name:
xiao hong
Hi xiao hong!
From the str we read:
We love Go 1314

Scan()函数原型为:

func Scan(a ...interface{}) (n int, err error) {
return Fscan(os.Stdin, a...)
}

Scan从标准输入扫描文本,将成功读取的空白分隔的值保存进成功传递给本函数的参数。换行视为空白。返回成功扫描的条目个数和遇到的任何错误。如果读取的条目比提供的参数少,会返回一个错误报告原因。

Scanln()函数原型为:

func Scanln(a ...interface{}) (n int, err error) {
return Fscanln(os.Stdin, a...)
}

Scanln类似于Scan,但会在换行符处停止扫描,在最后一个条目后必须有换行符或EOF。

Scanf()函数原型为:

func Scanf(format string, a ...interface{}) (n int, err error) {
return Fscanf(os.Stdin, format, a...)
}

Scanf从标准输入扫描文本,根据format参数指定的格式将成功读取的空白分隔的值保存进成功传递给本函数的参数。返回成功扫描的条目个数和遇到的任何错误。

输入中的换行符必须与格式中的换行符匹配。

Sscanf()函数原型为:

func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
return Fscanf((*stringReader)(&str), format, a...)
}

Sscanf从字符串str扫描文本,根据format参数指定的格式将成功读取的空白分隔的值保存进成功传递给本函数的参数。返回成功扫描的条目个数和遇到的任何错误。

输入中的换行符必须与格式中的换行符匹配。

Scan与Scanln方法的区别:

  • Scan函数会识别空格左右的内容,哪怕换行符存在也不会影响Scan对内容的获取。
  • Scanln函数会识别空格左右的内容,但是一旦遇到换行符就会立即结束,不论后续还是否存在需要输入的内容。

使用bufio包里带缓冲的Reader实现带空格字符串的输入

package main

import (
"bufio"
"fmt"
"os"
)
//var inputReader *bufio.Reader
//var input string
//var err error func main() { inputReader := bufio.NewReader(os.Stdin) // 使用了自动类型推导,不需要var关键字声明
//inputReader = bufio.NewReader(os.Stdin) fmt.Println("Please input your name: ") //input, err = inputReader.ReadString('\n')
input, err := inputReader.ReadString('\n') if err == nil {
fmt.Printf("Your name is: %s\n", input)
}
}

若输入为:

xiao hua

则输出为:

Please input your name:
xiao hua
Your name is: xiao hua

上例中,inputReader是个指针,它指向一个bufio类的Reader,然后在main函数里,通过bufio.NewReader(os.Stdin)

创建了一个buffer Reader,并联接到inputReader这个变量。

bufio.NewReader()函数原型为:

func NewReader(rd io.Reader) *Reader {
return NewReaderSize(rd, defaultBufSize)
}

任何符合io.Reader接口的对象法都可以作为bufio.NewReader()里的参数,并返回一个新的带缓冲的io.Reader,os.Stdin符合这个条件。这个带缓冲的Reader有一个方法ReadString(delim byte), 这个方法会一直读数据,直到遇到了指定的终止符(delim byte)才结束输入,终止符将成为输入的一部分,一起放到buffer里。

RearString()函数原型为:

func (b *Reader) ReadString(delim byte) (string, error) {
bytes, err := b.ReadBytes(delim)
return string(bytes), err
}

ReadString返回值是读到的字符串及nil。如果在读到结束时没有发现指定的结束符(delim byte),将返回一个 err != nil。在上面的例子中,我们从键盘输入直到键入“\n”才结束。屏幕是标准输出os.Stdout,错误信息被写到os.Stderr。大多情况下,os.Stderr等同os.Stdout。

一般情况下,在GO的代码里省略了变量声明,而直接使用”:=“进行自动类型推导,如:

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

总结

GO中Scan_或Sscan_系列函数与C中的scan_系统函数的用法相似,学过C的人可以很快学会这些函数的使用。但要实现带空格字符串的输入,则要使用bufio包里带缓冲的Reader和os包里的os.Stdin。


个人主页:

www.codeapes.cn

GO语言学习笔记1-输入带空格的字符串的更多相关文章

  1. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  2. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  3. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  4. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  5. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  6. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

  7. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  8. Go语言学习笔记十一: 切片(slice)

    Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...

  9. Go语言学习笔记十: 结构体

    Go语言学习笔记十: 结构体 Go语言的结构体语法和C语言类似.而结构体这个概念就类似高级语言Java中的类. 结构体定义 结构体有两个关键字type和struct,中间夹着一个结构体名称.大括号里面 ...

随机推荐

  1. 一文搞懂HTTP和HTTPS协议

    1.什么是协议? 网络协议是计算机之间为了实现网络通信而达成的一种"约定"或者"规则",有了这种"约定",不同厂商的生产设备,以及不同操作系 ...

  2. 剑指Offer总结——用两个栈实现队列

    class Solution { public: void push(int node) { stack2.push(node); } int pop() { if(stack1.empty()){ ...

  3. 结构体封装高精度 大整数BigInt

    曾经很讨厌高精度,因为它很长,不好记,而且在不是很单纯的题目里面感觉很烦(一个数就是一个数组).在一道题目中出现的时候总是用一些奇技淫巧混过去(比如把两个$long$ $long$拼在一起). 现在. ...

  4. hive_server2的权限控制

    CDH的core-sit开启: 第一个false表示用系统用户来和hive用户的权限绑定,但经测试并没有生效,所以可以改为true 第二项设置成ALL,表示创建者对其创建的表拥有所有的权限,这样也是比 ...

  5. 浅谈Javascript数据属性与访问器属性

    ES5中对象的属性可以分为‘数据属性’和‘访问器属性’两种. 数据属性一般用于存储数据数值,访问器属性对应的是set/get操作,不能直接存储数据值. 数据属性特性:value.writable.en ...

  6. 在.NET Core 3.0中发布单个Exe文件(PublishSingleFile)

    原文:在.NET Core 3.0中发布单个Exe文件(PublishSingleFile) 假设我有一个简单的" Hello World"控制台应用程序,我想发送给朋友来运行.朋 ...

  7. 2019-11-29-VisualStudio-2019-尝试使用-C#-8.0-新的方式

    title author date CreateTime categories VisualStudio 2019 尝试使用 C# 8.0 新的方式 lindexi 2019-11-29 08:41: ...

  8. error: (-215) !empty() in function detectMultiScale

    tips: pip install opencv-python or https://www.lfd.uci.edu/~gohlke/pythonlibs/ 原因确实是找不到 opencv 的 xml ...

  9. centos7 安装部署zabbix客户端

    1.下载安装zabbix-agent: # rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2. ...

  10. SpringBoot页面展示Thymeleaf

    https://www.jianshu.com/p/a842e5b5012e 开发传统Java WEB工程时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用了.Spring ...