5

現時点で私を悩ませている問題があります。ユーザーからの入力を取得するときに、ループを使用して、ユーザーが有効な入力を入力するまで再試行するように求めます。

// user_input.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Please enter an integer: ")

    var userI int

    for {
        _, err := fmt.Scanf("%d", &userI)
        if err == nil {
            break
        }
        fmt.Println("Sorry, invalid input. Please enter an integer: ")
    }

    fmt.Println(userI)    
}

上記を実行し、ユーザーが有効な入力を入力した場合、問題はありません:

整数を入力してください: <br> 3

3

終了コード 0、プロセスは正常に終了しました。

しかし、代わりに文字列を入力してみてください。

整数を入力してください: <strong>何?
入力が無効です。整数を入力してください:

無効な入力です。整数を入力してください:

申し訳ありません...

など、文字列が使い果たされるまで、文字ごとにループし続けます。1文字入力しても2回ループしますが、改行を解析していると思います。

とにかく、Go で Stdin をフラッシュする方法が必要ですか?

PSそのような機能がない場合、同等の機能を提供するためにどのように回避しますか? 私もそれで失敗した...

4

6 に答える 6

1

これはすでに回答されていることは知っていますが、これが私の実装でした:

func flush (reader *bufio.Reader) {
    var i int
    for i = 0; i < reader.Buffered(); i++ {
        reader.ReadByte()
    }
}

これは、「stdin.ReadString('\n')」を使用できない場合を含め、あらゆる状況で機能するはずです。

于 2013-02-25T07:38:13.043 に答える
0

これを掘り下げて申し訳ありませんが、今日これに遭遇し、新しい標準ライブラリ機能を使用して既存の回答を改善したいと考えました。

import (
    "bufio"
    "fmt"
    "os"
)

func discardBuffer(r *bufio.Reader) {
    r.Discard(r.Buffered())
}

stdin := bufio.NewReader(os.Stdin)
var i int
for true {
    if _, err := fmt.Fscanln(stdin, &i); err != nil {
        discardBuffer(stdin)
        // Handle error, display message, etc.
        continue
    }
    // Do your other value checks and validations
    break
}

基本的な考え方は、読み取りを常に標準入力からバッファリングすることです。スキャン中にエラーが発生した場合は、バッファの内容を破棄してください。そうすれば、次のスキャンのために空のバッファから開始できます。

または、スキャンする前にバッファを破棄することもできます。これにより、それ以前のユーザーによる迷走入力は取得されません。

func fscanln(r *bufio.Reader, a ...interface{}) error {
    r.Discard(r.Buffered())
    _, err := fmt.Fscanln(r, a...)
    return err
}

stdin := bufio.NewReader(os.Stdin)
var i int
if err := fscanln(stdin, &i); err != nil {
    // Handle error
}
于 2017-02-05T07:39:54.533 に答える