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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

968閲覧

メインメソッドでの入力と、違うクラスでの入力の際の挙動が違う

CR_GARO

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/06/30 17:32

###前提・実現したいこと
最初に二つの数を入力してもらい、その二数の積だけ整数値の入力を受け取るプログラムを書いていました。

例として、以下の値をコンソールにコピーアンドペーストしました。
3 3
1 2 -2
4 5 -1
7 3 6

この例だと3*3=9個の入力を受け取る(9個の入力は下の1,2,-2,4,5,-1,7,3,6です)
###発生している問題・エラーメッセージ

上手くsc.nextInt()が入力を受け取ってくれない

import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); Calc keisan = new Calc(); keisan.seki(n,m); sc.close(); } } class Calc{ void seki(int n, int m){ Scanner sc = new Scanner(System.in); int[] kazu = new int[n*m]; for(int i =0;i<n*m;i++){ kazu[i] = sc.nextInt(); } sc.close(); } } ```Java ###試したこと 発生している問題にある通り、上の書き方だと入力待ち(最下段の7 3 6だけは入力されてる)状態になってしまい 思ったように動きません。 この入力部分を全てメインメソッドに移して、呼び出す代わりにメインメソッド内で処理させると上手く動作しましたが、その理由がわかりません。 ###補足情報(言語/FW/ツール等のバージョンなど) Eclipseを使って勉強していました。

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

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

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

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

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

guest

回答3

0

ベストアンサー

Scannerクラスはコンストラクターに渡した入力ストリームから文字を「先読み」します。
先読みというのは実際にデータが必要になる前にずっと先の方まで読み込んでしまう動作のことを言います。

この例でいいますとmainメソッドの最初のnextIntの呼び出し時にコンソールから入力した4行分の文字は全てmainメソッドで生成したScannerインスタンスが読み込んでしまいます。

同じ入力元(System.in)からスキャンするのであれば別々のScannerインスタンスを生成してはならず、常に同一のScannerインスタンスを用いなければなりません。

質問者さんのコードに当てはめるなら、sekiメソッドへmainメソッドからScannerインスタンスを引数として渡せば期待通りに動きます。


追記:他の方の回答と矛盾してはいないと思うので追記しました。

自分が動かしたときは、質問者さんと同様に「最初に4行分をコピー&ペーストでコンソールへ張り付ける」ということをしました。こうするとmainメソッドの最初のnextIntでSystem.inから4行分全部読み込まれてしまいます。

ScannerはInputStreamから文字をデコードするためにデフォルトで1024文字分のバッファーを持っており、InputStreamから読み込めるだけそのバッファーへ文字をデコードしてしまいます。よって最初に1行しか入力しない状態で動かせばオリジナルのコードのままでも動きます。それが他の方の回答にある内容だと思います。

しかし前述のとおり最初から4行分をコピー&ペーストで入力すると期待通りには動きませんので、Scannerのインスタンスを複数作らないのがプログラムとしての正しい対処だと思います。

投稿2017/07/01 01:39

編集2017/07/01 02:01
KSwordOfHaste

総合スコア18394

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

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

CR_GARO

2017/07/01 14:53

Scannerクラスの性質が分かり、また何故そのような挙動になってしまったかも理解でき、勉強になりました。ありがとうございます。
guest

0

全部入力された値は入っているようですよ。

提示されたコードには、入力された値がどこにも出力されていないのでデバッグモードで試しています。
どこにもデータを出力されていないコードなので、再度書いたコードと入力の方法を確認すると良いでしょうか…。

デバッグモードで確認

投稿2017/07/01 01:44

A-pZ

総合スコア12011

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

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

CR_GARO

2017/07/01 14:56

回答ありがとうございます。出力を書き忘れていました。申し訳ありません。
guest

0

いまいちやりたい事がわかりませんが、
Scanner sc = new Scanner(System.in);
が void sekiの中にもあるためではないでしょうか?

コピペで入力数字を全部いれるのではなく、最初に"3 3"と打ちこんで、その後3×3の数字をコピペすれば望みの結果になりそうですよね?

投稿2017/06/30 18:37

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

CR_GARO

2017/07/01 14:50

質問の意図がわかりにくく、申し訳ありません。 動作の方はその通りに入力したら希望する動作をしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問