Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

go

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))
}
like image 513
Zeynel Avatar asked Jul 01 '13 09:07

Zeynel


People also ask

What is fmt scanln?

The fmt. Scanln() function in Go language scans the input texts which is given in the standard input, reads from there and stores the successive space-separated values into successive arguments. This function stops scanning at a newline and after the final item, there must be a newline or EOF.


1 Answers

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  
like image 112
peterSO Avatar answered Oct 23 '22 05:10

peterSO