无效浮动的意外循环

在我下面的代码中,当用户正确地浮动时,它可以正常工作。但是,当他们输入一些随机字符串时,它会打印错误消息并再次提示每个字符。这是为什么?


package main


import "fmt"


func readFloat(title string) float64 {

  var userInput float64


  for {

    fmt.Println("Please enter a float: ")

    _, err := fmt.Scanf("%f", &userInput)


    if err != nil {

      fmt.Printf("Wooops! That's not a float\n")

    } else {

      return userInput

    }

  }

}


func main() {

  var f float64


  f = readFloat("acceleration")

    fmt.Printf("You entered: %.04f\n", f)

}

~/src/coursera/go/course-2-functions-methods/week2 $ go run so.go

Please enter a float:

33.3

You entered: 33.3000

~/src/coursera/go/course-2-functions-methods/week2 $ go run so.go

Please enter a float:

sdf

Wooops! That's not a float

Please enter a float:

Wooops! That's not a float

Please enter a float:

Wooops! That's not a float

Please enter a float:

Wooops! That's not a float

Please enter a float:


呼唤远方
浏览 137回答 2
2回答

慕无忌1623718

问题是,如果fmt.Scanf()遇到无效输入,它将停止消耗它。例如,您想使用 解析浮点数%f,但如果用户输入sdf,fmt.Scanf()将知道它在第一个s字符后无效,因此返回错误并且不会消耗其余字符。因此,下一个循环迭代开始,它消耗第二个字符d,这又是无效的等等。s2例如,如果您尝试输入,这一点就会变得清晰:Please enter a float: s2Wooops! That's not a floatPlease enter a float: You entered: 2.0000第一个schar 无效,但下一次迭代将解析2。“修复”此问题的一种方法是将整行读取为字符串,然后尝试从字符串中解析浮点数。要读取一行,请使用bufio.Scanner,要解析浮点数,请使用strconv.ParseFloat()。以下是如何执行此操作的示例:func readFloat(title string) float64 {    scanner := bufio.NewScanner(os.Stdin)    for {        fmt.Printf("Please enter a float for %s: ", title)        if !scanner.Scan() {            fmt.Println("Error readling line")            return 0 // Should return an error too!        }        line := scanner.Text()        userInput, err := strconv.ParseFloat(line, 64)        if err == nil {            return userInput        }        fmt.Printf("Wooops! That's not a float\n")    }}

一只斗牛犬

这是因为如果用户输入错误的值,您的 for 循环将是无限循环。return您应该在 后面有一个语句fmt.Printf("you entered wrong number"),以便 for 循环可以退出。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go