fmt包中提供了3類讀取輸入的函數:函數
其中:code
這3家族的函數都返回讀取的記錄數量,並會設置報錯信息,例如讀取的記錄數量不足、超出或者類型轉換失敗等。orm
如下是它們的定義方式:對象
$ go doc fmt | grep -Ei "func [FS]*Scan" func Fscan(r io.Reader, a ...interface{}) (n int, err error) func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) func Fscanln(r io.Reader, a ...interface{}) (n int, err error) func Scan(a ...interface{}) (n int, err error) func Scanf(format string, a ...interface{}) (n int, err error) func Scanln(a ...interface{}) (n int, err error) func Sscan(str string, a ...interface{}) (n int, err error) func Sscanf(str string, format string, a ...interface{}) (n int, err error) func Sscanln(str string, a ...interface{}) (n int, err error)
由於還沒介紹io.Reader,因此Fscan家族的函數暫且略過,但用法和另外兩家族的scan類函數是同樣的。字符串
Scan家族函數從標準輸入讀取數據時,將以空格爲分隔符分隔標準輸入中的內容,並將分隔後的各個記錄保存到給定的變量中。其中Scanf()能夠指定分隔符。input
例如,使用Scanln函數等待用戶輸入數據,或從管道中讀取數據。下面的代碼將等待用戶輸入,且將讀取的內容分別保存到name變量和age變量中:string
package main import ( "fmt" ) func main() { var ( name string age int ) fmt.Print("輸入姓名和年齡,使用空格分隔:") fmt.Scanln(&name, &age) fmt.Printf("name: %s\nage: %d\n", name, age) }
由於Scanln()遇到換行符或EOF的時候終止讀取,因此在輸入的時候只要按下回車鍵就會結束讀取。io
運行它,將提示輸入姓名:form
請輸入姓名和年齡,空格分隔: 周伯通 69 name: 周伯通 age: 69
同理Scanf()也在遇到換行符或EOF的時候終止讀取行爲。使用Scanf()的時候,須要給定格式化字符串形式:
例如:import
fmt.Scanf("%s %d",&name,&age)
輸入時,第一個字段會轉換成字符串格式保存到name
變量中,第二個記錄會轉換成整數保存到age
中,若是轉換失敗,將不會進行保存。例如輸入malongshuai aaa
,因爲aaa
沒法轉換成int,因此age變量的值仍然爲初始化的數值0。
Scanf可指定分隔符,其中上面的是%s %d
中間的空格就是分隔符。例以下面指定:
做爲分隔符:
fmt.Scanf("%s : %d",&name,&age)
在輸入時,必須按照如下格式進行輸入:首先至少一個空格,而後一個冒號,再至少一個空格:
周伯通 : 23 // 或者連續多個空格 "周伯通 : 23" name: 周伯通 age: 23
若是使用的是fmt.Scan()
,則輸入數據時能夠換行輸入,Scan()會將換行符做爲空格進行處理,直到讀取到了2個記錄以後自動終止讀取操做:
fmt.Scan(&name, &age) 請輸入姓名和年齡,空格分隔:周伯通 87 name: 周伯通 age: 87
通常來講,只使用Scanf類函數比較好。
這些函數都有返回值:讀取的記錄數量和err信息。
以Scanln()爲例:
func main() { var ( name string age int ) fmt.Print("輸入姓名和年齡,使用空格分隔:") n, err := fmt.Scanln(&name, &age) fmt.Printf("name: %s\nage: %d\n", name, age) fmt.Println("records count:",n) fmt.Println("err or not:",err) }
輸入:
malongshuai 23 // n = 2, err = nil malongshuai // n = 1, err != nil malongshuai long // n = 2, err != nil malongshuai 23 23 // n = 2, err != nil
Sscan家族的函數用於從給定字符串中讀取數據,用法和Scan家族相似。
func Sscan(str string, a ...interface{}) (n int, err error) func Sscanln(str string, a ...interface{}) (n int, err error) func Sscanf(str string, format string, a ...interface{}) (n int, err error)
例如:
package main import ( "fmt" ) func main() { var ( name string age int ) input := "malongshuai 23" fmt.Sscan(input, &name, &age) fmt.Printf("name: %s\nage: %d\n", name, age) }
使用Sscanf()能夠指定分隔符:
input := "malongshuai : 23" fmt.Sscanf(input, "%s : %d", &name, &age)
除了fmt包的Scan類函數,bufio包也能夠讀取標準輸入。固然,讀取標準輸入只是它的一個功能示例,它的做用是操做緩衝IO。
package main import ( "bufio" "fmt" "os" ) var inputReader *bufio.Reader var input string var err error func main() { inputReader = bufio.NewReader(os.Stdin) fmt.Println("輸入姓名:") input, err = inputReader.ReadString('\n') if err == nil { fmt.Printf("The input was: %s\n", input) } }
其中NewReader()建立一個bufio.Reader實例,表示建立一個從給定文件中讀取數據的讀取器對象。而後調用讀取器對象(Reader實例)的ReadString()方法,這個方法以\n
做爲分隔符,它的分隔符必須只能是單字符,且必須使用單引號包圍,由於它會做爲byte讀取。ReadString()讀取來自os.Stdin的內容後將其保存到input變量中,同時返回是否出錯的信息。ReadString()只有一種狀況會返回err:沒有遇到分隔符。
ReadString會將讀取的內容包括分隔符都一塊兒放進緩衝中,若是讀取文件時讀到告終尾,則會將整個文件內容放進緩衝,並將文件終止標識符io.EOF放進設置爲err。
一般無需單獨定義這些變量,下面是更常見的用法。
inputReader := bufio.NewReader(os.Stdin) input, err := inputReader.ReadString('\n')