Go語(yǔ)言中三個(gè)輸入函數(shù)(scanf,scan,scanln)的區(qū)別解析
Go語(yǔ)言中三個(gè)輸入函數(shù)(scanf,scan,scanln)的區(qū)別
在 Go 語(yǔ)言中,fmt 包提供了三種輸入函數(shù):Scanf、Scan 和 Scanln。這三個(gè)函數(shù)都是用于從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)并存儲(chǔ)到變量中,但是它們?cè)谔幚磔斎氲姆绞缴嫌兴煌?。下面詳?xì)解讀每個(gè)函數(shù)的特點(diǎn)和用法。
1. fmt.Scanf
- 用法:fmt.Scanf(format string, a …interface{}) (n int, err error)
- 功能:根據(jù)格式化字符串 format 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),并將數(shù)據(jù)存儲(chǔ)到提供的參數(shù)中。格式化字符串類似于 C 語(yǔ)言中的 scanf,例如 %d 表示讀取一個(gè)整數(shù),%s 表示讀取一個(gè)字符串。
- 輸入終止條件:Scanf 讀取輸入時(shí),會(huì)忽略空白字符,并且根據(jù)格式化字符串解析輸入內(nèi)容。輸入可以包含換行符,但解析會(huì)按照格式字符串中的要求進(jìn)行。
示例代碼:
package main import ( "fmt" ) func main() { var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(格式如:123 hello):") fmt.Scanf("%d %s", &a, &b) // 根據(jù)格式化字符串讀取 fmt.Println("整數(shù):", a) fmt.Println("字符串:", b) }
注意:
如果輸入的格式與指定的格式字符串不匹配,可能會(huì)導(dǎo)致讀取失敗或產(chǎn)生意外結(jié)果。
2. fmt.Scan
- 用法:fmt.Scan(a …interface{}) (n int, err error)
- 功能:讀取由空格分隔的輸入數(shù)據(jù),并將數(shù)據(jù)存儲(chǔ)到提供的參數(shù)中。它不需要格式化字符串,而是依次將輸入的值賦給傳入的變量。
- 輸入終止條件:輸入以空格或換行符為分隔符,讀取的值必須與傳入的參數(shù)數(shù)量匹配。
示例代碼:
package main import ( "fmt" ) func main() { var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(用空格分隔):") fmt.Scan(&a, &b) // 直接讀取輸入到變量中 fmt.Println("整數(shù):", a) fmt.Println("字符串:", b) }
注意:
- 輸入數(shù)據(jù)必須能正確解析為指定的變量類型,否則會(huì)出現(xiàn)錯(cuò)誤。
- 如果輸入的值數(shù)量與變量數(shù)量不匹配,程序會(huì)等待進(jìn)一步的輸入。
3. fmt.Scanln
- 用法:fmt.Scanln(a …interface{}) (n int, err error)
- 功能:與 fmt.Scan 類似,但會(huì)在讀取完所有指定的參數(shù)后檢查是否有多余的輸入。它要求讀取的最后一個(gè)輸入?yún)?shù)必須位于行的末尾,否則會(huì)返回一個(gè)錯(cuò)誤。
- 輸入終止條件:讀取到換行符結(jié)束,并要求讀取的參數(shù)數(shù)量與傳入的變量數(shù)量匹配。
示例代碼:
package main import ( "fmt" ) func main() { var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(用空格分隔,并按回車結(jié)束):") fmt.Scanln(&a, &b) // 讀取輸入到變量中,并檢查換行 fmt.Println("整數(shù):", a) fmt.Println("字符串:", b) }
注意: 如果輸入的值數(shù)量與傳入的變量數(shù)量不匹配,或者在讀取所有參數(shù)后還有多余的輸入,則會(huì)返回錯(cuò)誤。 總結(jié)比較
- Scanf 更加靈活,可以指定格式,但要求輸入格式必須匹配。
- Scan 和 Scanln 更適合簡(jiǎn)單的輸入讀取,Scanln 還會(huì)檢查是否有多余的輸入。
在實(shí)際應(yīng)用中,根據(jù)需要選擇適當(dāng)?shù)暮瘮?shù)來(lái)讀取用戶輸入。
這三種函數(shù),都會(huì)將換行符,一起讀取嗎?
在 Go 語(yǔ)言中,fmt.Scanf、fmt.Scan 和 fmt.Scanln 這三個(gè)函數(shù)處理?yè)Q行符的方式有所不同。讓我們?cè)敿?xì)解釋它們對(duì)換行符的處理:
1. fmt.Scanf
- 換行符處理:Scanf 不會(huì)將換行符視為特殊的輸入結(jié)束標(biāo)記,它會(huì)根據(jù)指定的格式化字符串來(lái)解析輸入數(shù)據(jù)。
- 輸入中包含換行符:如果換行符符合格式化字符串的要求,它會(huì)被視為空白字符而被忽略,否則會(huì)被保留在輸入流中等待下一次讀取。
示例:
var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(如:123 hello):") fmt.Scanf("%d %s", &a, &b) // 如果輸入 "123\nhello",換行符會(huì)被忽略
在這個(gè)例子中,輸入時(shí)如果用戶輸入 “123\nhello”,換行符會(huì)被忽略,因?yàn)樗皇欠指袅藘蓚€(gè)數(shù)據(jù)。
2. fmt.Scan
- 換行符處理:Scan 將換行符視為空白字符,與空格一樣被忽略。它會(huì)繼續(xù)讀取輸入,直到滿足所有變量的賦值。
- 連續(xù)輸入的情況:即使輸入中有換行符,Scan 仍然會(huì)嘗試從輸入流中讀取更多的數(shù)據(jù),直到滿足要求的變量數(shù)量。
示例:
var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(用空格分隔):") fmt.Scan(&a, &b) // 如果輸入 "123\nhello",換行符會(huì)被忽略
在這個(gè)例子中,輸入 “123\nhello” 時(shí),Scan 會(huì)忽略換行符并繼續(xù)讀取輸入,直到讀取到字符串 “hello”。
3. fmt.Scanln
- 換行符處理:Scanln 會(huì)將換行符作為輸入的結(jié)束標(biāo)志。當(dāng)所有的輸入?yún)?shù)都讀取完畢后,Scanln 要求輸入流中不能有多余的數(shù)據(jù)。如果有多余的數(shù)據(jù),即使是換行符,也會(huì)返回錯(cuò)誤。
- 換行符終止:它要求最后一個(gè)輸入?yún)?shù)之后必須是換行符,否則會(huì)報(bào)錯(cuò)。
示例:
var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(用空格分隔,并按回車結(jié)束):") fmt.Scanln(&a, &b) // 如果輸入 "123 hello\n",換行符作為結(jié)束標(biāo)志
在這個(gè)例子中,輸入 “123 hello\n” 時(shí),Scanln 會(huì)正常讀取到整數(shù)和字符串,并認(rèn)為換行符是輸入的結(jié)束標(biāo)志。
總結(jié)
- Scanf:根據(jù)格式化字符串解析輸入,換行符如果不影響解析會(huì)被忽略。
- Scan:將換行符視為空白字符,會(huì)繼續(xù)讀取更多數(shù)據(jù),直到滿足所有變量的賦值要求。
- Scanln:以換行符作為輸入結(jié)束標(biāo)志,如果在所有參數(shù)讀取完畢后還有多余輸入(除了換行符),會(huì)返回錯(cuò)誤。
換行符是否被讀取取決于函數(shù)的設(shè)計(jì)和用法,Scanln 是唯一一個(gè)明確要求換行符作為結(jié)束標(biāo)志的函數(shù)。
輸入中包含換行符:如果換行符符合格式化字符串的要求,它會(huì)被視為空白字符而被忽略,否則會(huì)被保留在輸入流中等待下一次讀取。
對(duì)上面加粗部分的解釋:
為了更好地理解 fmt.Scanf 如何處理輸入中的換行符,下面舉一個(gè)具體的例子來(lái)說(shuō)明這種行為。
例子
package main import ( "fmt" ) func main() { var a int var b string fmt.Print("請(qǐng)輸入一個(gè)整數(shù)和一個(gè)字符串(格式:123 hello):") fmt.Scanf("%d %s", &a, &b) fmt.Println("a:", a) fmt.Println("b:", b) }
示例 1:
- 輸入內(nèi)容:123 hello,然后按下 Enter(實(shí)際上輸入的是 “123 hello\n”)。
- 執(zhí)行過(guò)程:
a.fmt.Scanf(“%d %s”, &a, &b) 嘗試按格式化字符串 %d %s 解析輸入數(shù)據(jù)。
b.%d 匹配到整數(shù)部分,讀取 123,成功解析并賦值給變量 a。
c.%s 匹配到字符串部分,讀取 hello,成功解析并賦值給變量 b。
d.剩余的換行符 \n 被 Scanf 視為分隔符(空白字符)而忽略掉。
結(jié)果: 輸出:
a: 123 b: hello
示例 2:輸入 “123\nhello”
- 輸入內(nèi)容:123,按下 Enter 鍵(輸入 “123\n”),然后再輸入 hello 并按下 Enter。
- 執(zhí)行過(guò)程:
a.fmt.Scanf(“%d %s”, &a, &b) 首先嘗試解析 %d,從輸入 “123\n” 中讀取到整數(shù) 123 并賦值給 a。
b.接下來(lái),fmt.Scanf 嘗試讀取 %s,但此時(shí)輸入流中的字符是換行符 \n,它不符合字符串的格式要求。因此,Scanf 讀取 %s 的嘗試失敗,換行符 \n 被保留在輸入流中等待下一次讀取。
c.因?yàn)樽x取 %s 失敗,b 沒(méi)有被賦值,程序繼續(xù)等待下一個(gè)輸入。
d.當(dāng)用戶再輸入 hello 并按下 Enter 后,Scanf 成功讀取到字符串 hello 并賦值給 b。
結(jié)果: 輸出:
a: 123
b: hello
解釋
在示例 1 中,“123 hello\n” 中的換行符被視為空白字符,符合格式化字符串的要求,因此被忽略。而在示例 2 中,“123\nhello” 中的換行符不符合 %s 的格式要求,導(dǎo)致 Scanf 讀取失敗,換行符保留在輸入流中,等待下一次讀取。
這展示了 fmt.Scanf 處理?yè)Q行符的兩種情況:符合格式時(shí)忽略,不符合時(shí)保留在輸入流中。
到此這篇關(guān)于Go語(yǔ)言中三個(gè)輸入函數(shù)(scanf,scan,scanln)的區(qū)別的文章就介紹到這了,更多相關(guān)Go 輸入函數(shù)scanf,scan,scanln內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver)
這篇文章主要介紹了golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver),本文通過(guò)截圖實(shí)例代碼的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02

Go中g(shù)in框架的*gin.Context參數(shù)常見(jiàn)實(shí)用方法

Go可變參數(shù)函數(shù)的實(shí)現(xiàn)

golang對(duì)自定義類型進(jìn)行排序的解決方法