質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

2回答

1464閲覧

Go ループ下のScanfについて

NagaseKouiti

総合スコア14

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

2グッド

1クリップ

投稿2020/03/13 10:29

編集2020/03/15 08:41

前提・実現したいこと

プログラミング初心者です

最近Go言語の学習を始め
手始めに簡易な○×ゲームを作成しようと考えたのですが
二回目のscanfにて
意図しない動作をしたので質問させていただきます

予定している動作にならない理由と、
解決方法を教えていただきたいです

コンパイルエラーは出ておりません

該当のソースコード

GO

1package main 2 3import ( 4 "fmt" 5 "strings" 6) 7 8var ( 9 flag bool 10 first, second int 11 12 board = [][]string{ 13 []string{"-", "-", "-"}, 14 []string{"-", "-", "-"}, 15 []string{"-", "-", "-"}, 16 } 17) 18 19func input(board [][]string) { 20 for { 21 fmt.Println("あなたのターンです 丸を付ける箇所を入力してください") 22 fmt.Scanf("%d %d", &first, &second) 23 24 switch { 25 case first < 0 || second < 0: 26 fallthrough 27 case first > 2 || second > 2: 28 fmt.Println("0 ~ 2 の値で入力して下さい") 29 continue 30 case board[first][second] == "○" || board[first][second] == "×": 31 fmt.Println("既に値が格納されています") 32 continue 33 default: 34 board[first][second] = "○" 35 return 36 } 37 } 38} 39 40func print() { 41 for i := 0; i < len(board); i++ { 42 fmt.Println(strings.Join(board[i], " ")) 43 } 44} 45 46func result() { 47 fmt.Println() 48 return 49} 50 51func main() { 52 fmt.Println("●×ゲームです あなたは●で先行です") 53 for { 54 55 //ユーザーが値を入力する 56 input(board) 57 58 //結果の出力 59 print() 60 61 //勝利or敗北したときのbreak 62 //未実装 63 //if flag { 64 //result() 65 //} 66 } 67}

動作状況

●×ゲームです あなたは●で先行です
あなたのターンです 丸を付ける箇所を入力してください
1 1
:- - -:
:- ○ -:
:- - -:
あなたのターンです 丸を付ける箇所を入力してください
既に値が格納されています **二回目のscanfが入力しないままスルーされる**
あなたのターンです 丸を付ける箇所を入力してください
| **なぜか三回目のscanfは入力を待ってもらえる**

補足情報

go version go1.14 windows/amd64
イメージ説明

DrqYuto, s.k👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

あなたのターンです 丸を付ける箇所を入力してください
既に値が格納されています **二回目のscanfが入力しないままスルーされる**
あなたのターンです 丸を付ける箇所を入力してください
| **なぜか三回目のscanfは入力を待ってもらえる**

この二行目のコメントで「スルー」という意味がわかりません。

「あなたのターンです 丸を付ける箇所を入力してください」という表示とScanfは記述通り
必ずセット動作するはずなので、「既に値が格納されています」の表示段階でScanfが処理されることはありません。

投稿2020/03/14 06:16

nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NagaseKouiti

2020/03/15 08:08 編集

返信が遅れました 実行結果は正しくscanfをスルーしているという考え方が間違っているということでしょうか? それとも実行結果の記述がありえないということでしょうか?
nobonobo

2020/03/15 08:19

いえ、コメントの二回目のScanfというのがどこなのかがわからないのです。具体的にどの行を指していますか?
NagaseKouiti

2020/03/15 08:24 編集

fmt.Scanf("%d %d", &first, &second) の箇所です 下部のmain関数でfor文を回しているので自動的に同じinput関数が使用されるようになってます
d_tutuz

2020/03/15 08:29

「二回目のscanfが入力しないままスルーされる」という動作はおきないと思います。 一応、手元のローカルの環境(go version go1.14 windows/amd64)で動作させた結果です ●×ゲームです あなたは●で先行です あなたのターンです 丸を付ける箇所を入力してください 1 1 - - - - ○ - - - - あなたのターンです 丸を付ける箇所を入力してください 0 1 - ○ - - ○ - - - - あなたのターンです 丸を付ける箇所を入力してください
NagaseKouiti

2020/03/15 08:39

あまり考えたくはなかったのですが実行環境の問題かもしれません 私の実行画面では入力を待ってもらえずにswitch文に突入します 写真を追加しておきます
NagaseKouiti

2020/03/15 08:51 編集

この質問はGo言語の領域ではないと判断したため 身勝手ながら質問を打ち切らせていただきます 回答していただいた方々、ありがとうございました
guest

0

ベストアンサー

環境の問題ではありますが、Go の scanf の仕様によるもので、おそらく以下の回答が参考になります。

結論としては以下のように修正することで、想定されている動作が実現できます。

diff

1-fmt.Scanf("%d %d", &first, &second) 2+fmt.Scanf("%d %d\n", &first, &second)

https://stackoverflow.com/questions/17401709/why-doesnt-fmt-scanf-in-go-wait-for-user-input/17403785

投稿2020/03/15 08:59

編集2020/03/15 09:00
d_tutuz

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NagaseKouiti

2020/03/15 09:06

綺麗に出来ました 本当にありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問