Why doesn't fmt.Scanf in Go wait for user input?

go

Solution

Update: was fixed almost a decade ago. The docs for `fmt` now read

In all the scanning functions, a carriage return followed immediately by a newline is treated as a plain newline (\r\n means the same as \n).

If you continue to have scanning errors, mind that it isn't your IDE's fault.

It's Issue 5391: `fmt`: `Scanf` rejects `\r\n` at end of line on Windows.

As a workaround and to check for valid input, write,

var inputSquare float64
n, err := fmt.Scanf("%f\n", &inputSquare)
if err != nil || n != 1 {
    // handle invalid input
    fmt.Println(n, err)
}

and

var inputGuess float64
n, err = fmt.Scanf("%f\n", &inputGuess)
if err != nil || n != 1 {
    // handle invalid input
    fmt.Println(n, err)
}

The workaround is the newline in the `"%f\n"` format strings.

Package `fmt`

func Scanf

func Scanf(format string, a ...interface{}) (n int, err error)

`Scanf` scans text read from standard input, storing successive space-separated values into successive arguments as determined by the format. It returns the number of items successfully scanned.

Here's a complete working program:

package main

import (
    "fmt"
)

// compute square roots by using Newton's method
func main() {
    var x float64 //number to take square root
    var y float64 //this is the guess
    var q float64 //this is the quotient
    var a float64 //this is the average

    fmt.Print("Enter a number to take its square root: ")
    var inputSquare float64
    n, err := fmt.Scanf("%f\n", &inputSquare)
    if err != nil || n != 1 {
        // handle invalid input
        fmt.Println(n, err)
        return
    }

    fmt.Print("Enter first guess ")
    var inputGuess float64
    n, err = fmt.Scanf("%f\n", &inputGuess)
    if err != nil || n != 1 {
        // handle invalid input
        fmt.Println(n, err)
        return
    }

    x = inputSquare
    y = inputGuess
    for i := 0; i < 10; i++ {
        q = x / y       // compute the quotient; x and y are given
        a = (q + y) / x // compute the average
        y = a           // set the guess to the average
    }
    fmt.Printf("sqrt(%g) = %g\n", x, y)
}

Output:

Enter a number to take its square root: 2.0
Enter first guess 1.0
sqrt(2) = 1.414213562373095

I used Go 1.1.1 on Windows 7:

C:\>go version
go version go1.1.1 windows/amd64  

Problem

I am working through Caleb Doxsey's Go book and I have two questions about `fmt.Scanf` http://www.golang-book.com/4 I am wondering why the program does not stop after the second Scanf and wait for user input? And how do I test if the user entered an integer and/or did not leave blank? ``` package main import ( "fmt" //"math" ) // compute square roots by using Newton's method func main() { var x float64 //number to take square root var y float64 //this is the guess var q float64 //this is the quotient var a float64 //this is the average // how do check if the user entered a number fmt.Print("Enter a number to take its square root: ") var inputSquare float64 fmt.Scanf("%f", &inputSquare) // why doesn't program stop after // the Print statement and wait // for user input? fmt.Print("Enter first guess ") var inputGuess float64 fmt.Scanf("%f", &inputGuess) //x = 2 x = inputSquare y = inputGuess for i := 0; i < 10; i++ { //set up the for loop for iterations q = x/y //compute the quotient; x and y are given a = (q + y) / x //compute the average y = a //set the guess to the average } //for the next loop fmt.Println("y --> ", y) //fmt.Println("Sqrt(2)", math.Sqrt(2)) } ```

Original source