跳至主要内容

[pkg] bufio

bufio @ golang

Type Reader

(b) ReadString(delim)

如果我們希望讀取使用者在 Terminal 輸入的文字,且這個文字超過一個以上的單字時,可以用 bufio.NewReader(os.Stdin) 來達到。

提示

如果希望從終端機取得的資料只包含一個單字,則可以使用 fmt.Scan() 方法。

reader.ReadString() 會讀取字串,直到遇到 delim 停止,並回傳包含 delim 以前的所有字串(這裡的 delim 就是 \n):

func main() {
// 從 Terminal 取得使用者輸入的內容
rd := bufio.NewReader(os.Stdin)

fmt.Println("Enter anything...: ")
// 當使用者按下 enter(\n) 後終止
message, err := rd.ReadString('\n')
if err != nil {
fmt.Println(err)
}

fmt.Printf("###%s###", message)
}

輸出:

###fff
###

若有需要可以將輸出的結果再透過 strings.TrimSpace() 的方法將 \n 過濾掉:

messageWithoutLineBreak := strings.TrimSpace(message)

type Scanner

官方文件

type Scanner @ pkg.go.dev

使用 Scanner 來讀取資料或字串

Scanner 提供方便的介面來讀取資料。使用 Scanner.Scan 可以把資料變成許多 "tokens",tokens 的切分是透過 SplitFunc 來決定,預設是以換行(例如,\n)來切分,透過 Scanner.Split 可以自己定義或選擇不同的 SplitFunc,例如換行(ScanLines)、bytes(ScanBytes)、UTF-8-encoded runes(ScanRunes)或以空格(ScanWords)來切分。

Scanning 會在 EOF、I/O error 或 token 太大無法存進 Scanner.Buffer 時停止,當 scan 停止時,reader 可能已經超越所讀到的 last token 許多。如果需要仔細控制 error handling、處理 large token 或必須在 reader 上循序 scan,這應該考慮使用 bufio.Reader

func main() {
s := "I felt so good like anything was impossible\nI hit cruise control and rubbed my eyes\nThe last three days\nthe rain was un-stoppable"

// 把字串放入 Reader 中,並建立 scanner
scanner := bufio.NewScanner(strings.NewReader(s))
// scanner := bufio.NewScanner(os.Stdin) // 如果要使用從 Terminal 讀進來的內容或檔案

// 把切分 token 的方式改成用 space 切分,預設是 ScanLines
scanner.Split(bufio.ScanWords)

for scanner.Scan() {
line := scanner.Text()
fmt.Println(line)
}
}