2013-07-01 19 views
5

私はカレブDoxseyの囲碁本を働いていると私はプログラムが第二scanfの後に停止し、ユーザーの入力を待ちませんなぜ私が疑問に思ってfmt.Scanfhttp://www.golang-book.com/4Goのfmt.Scanfがユーザー入力を待たないのはなぜですか?

について2つの質問がありますか?ユーザーが整数を入力したか、空白を残していないかどうかをテストするにはどうすればよいですか?

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)) 
} 
+1

それは私のために正常に動作します。私はそれが行末の問題であると推測するつもりです。 Windows上で走っているならば、行の終わりは通常 '\ r \ n'で表示されますが、Mac OS XとLinuxでは(これをテストしたところで)ただ\ nです。私の推測は、おそらくGoは '\ r'を読んでいて、行の終わりとして扱い、ストリームに '\ n'を残しているということです。 fmt.Scanfをもう一度呼び出すと、すでにバッファに何かがあり、ブロックする必要はありません。しかしこれはただの野生の推測です。 – deong

+0

どのようにそれを修正するための任意の提案?これは私がWindowsのコマンドラインで実行するものです:c:\ Go \ src \ play \ exercise> go loop_exercise.go 平方根を取るために数値を入力してください:2 最初の推測を入力y - > + Inf – Zeynel

+1

あなたが明示的に改行文字をScanf呼び出しで読むと、どうなるでしょうか? "fmt.Scanf("%f \ n "、&inputGuess)' "のように?あるいは、読み込みごとに標準入力をフラッシュすることもできます。私はFlush関数を探す場所を知るのに十分にうまくいくかどうかわかりません。 – deong

答えて

9

それはIssue 5391です:fmtScanfは、Windows上の行の末尾に\r\nを拒否します。回避策として

と書き込み、有効な入力をチェックするために、

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

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

回避策は"%f\n"書式指定文字列で改行です。

パッケージfmt

func Scanf

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

Scanfスキャンテキストは フォーマットによって決定されるように、連続する引数に連続 スペースで区切られた値を格納し、標準入力から読み取ら。正常にスキャンされたアイテムの数を返します。

ここでは完全な作業プログラムです:私は、Windows 7上でゴー1.1.1を使用

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

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) 
} 

は出力

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

'fmt.Scanf()'はエラーを返しますか?私は、 'n'は入力で、' err'は 'n、err:= fmt.Scanf("%f \ n "、&inputSquare)のエラーメッセージです。 – Zeynel

+1

改訂版の回答を参照してください。 'n'は正常にスキャンされたアイテムの数であり、' err'はスキャン中に遭遇したエラーを報告します。したがって、エラーがあった場合、またはスキャンした項目の数が期待通りでない場合( 'err!= nil || n!= 1')、エラーを処理するために何かをしてください。しかし、すべてがうまくいくと( 'err == nil && n == 1)、浮動小数点数(' float64')として有効な入力を '* inputSquare'から読み込むことができます。あなたのコードでは、 'n'と' err'を破棄したので、エラーに気付かなかったのです。 – peterSO

+0

私は間違ったことをする必要があります。エラー処理部 'n、err:= fmt.Scanf(" f \ n "、&inputSquare)を使ってプログラムを実行すると、エラー番号 \tが返されます。 "入力がフォーマットと一致しません"(私はinputSquareに2.0を入力します)エラー処理をコメントアウトすると、すべて正常に動作します。私は間違って何をしていますか? – Zeynel

関連する問題