Input fmt.Scanln预期换行错误

Input fmt.Scanln预期换行错误,input,go,Input,Go,我正试着学围棋,但还是坚持这个:或者 对于此输入: 123 123.456 everybody loves ice cream 结果是: read 1 integer: 123 read 1 float64: 123.456 read 1 string: everybody Error: Scan: expected newline 这是预期的行为吗?为什么它不能像C++ GETLIN那样工作? 答案如下: Scanln与Scan类似,但在换行时停止扫描,并且在最后一项之后必须有换行

我正试着学围棋,但还是坚持这个:或者

对于此输入:

123
123.456
everybody loves ice cream
结果是:

read 1 integer:  123
read 1 float64:  123.456
read 1 string:  everybody
Error:  Scan: expected newline
这是预期的行为吗?为什么它不能像C++ GETLIN那样工作? 答案如下:

Scanln与Scan类似,但在换行时停止扫描,并且在最后一项之后必须有换行或EOF

Scan
也会起作用:

扫描扫描从标准输入读取的文本,将连续的空格分隔值存储到连续的参数中。换行符算作空格。它返回成功扫描的项目数。如果这少于参数数量,err将报告原因

总之:
Scan
将每个单词(由空格分隔的字符串)放入相应的参数中,将换行符视为空格
Scanln
执行相同的操作,但将换行符视为停止字符,之后不再解析

如果要读取一行(
\n
结尾),请使用
bufio.Reader
及其方法:


作为一种解决方法,您可以实现自己的
fmt.Scanner

package main
import "fmt"

type newline struct { tok string }

func (n *newline) Scan(state fmt.ScanState, verb rune) error {
   tok, err := state.Token(false, func(r rune) bool {
      return r != '\n'
   })
   if err != nil {
      return err
   }
   if _, _, err := state.ReadRune(); err != nil {
      if len(tok) == 0 {
         panic(err)
      }
   }
   n.tok = string(tok)
   return nil
}

func main() {
   var n newline
   fmt.Scan(&n)
   fmt.Println(n.tok)
}

line, err := buffer.ReadString('\n')
package main
import "fmt"

type newline struct { tok string }

func (n *newline) Scan(state fmt.ScanState, verb rune) error {
   tok, err := state.Token(false, func(r rune) bool {
      return r != '\n'
   })
   if err != nil {
      return err
   }
   if _, _, err := state.ReadRune(); err != nil {
      if len(tok) == 0 {
         panic(err)
      }
   }
   n.tok = string(tok)
   return nil
}

func main() {
   var n newline
   fmt.Scan(&n)
   fmt.Println(n.tok)
}