4

ユーザー入力を受け取り、それを呼び出すメソッドに特定のデータ型として返すために以前に使用したメソッドがいくつかあります。私は以前のプロジェクトでこれらの方法、またはそれらのバリエーションを使用しました。

文字列に使用した方法を採用して、指定された最初の文字を選択して返し、これをメニューで使用できるようにしました。アプリケーションを起動するたびに、メイン メニューが表示され、ユーザーの入力を待ちます。この入力を受け取った後、プログラムは停止するまでループを繰り返します。文字をキャプチャするための私の方法は次のとおりです。

private char getUserChar(String prompt) {
    try {
        Scanner scan = new Scanner(System.in);
        System.out.print(prompt);
        String tempString = "";
        tempString = scan.nextLine();
        scan.close();
        char userChar = tempString.charAt(0);
        return userChar;
    } catch(Exception ex) {
        System.out.println(ex.getMessage());
    }
    return 0;
}

scan.nextLine() は次の入力を待機しないため、try/catch ブロックが原因でコードがループします。それがない場合、例外は通常、新しい行が見つからないことに関連しています。私は while(scan.hasNextLine()) を試しましたが、これは他の人にとってはうまくいくようです。ただし、入力の時間になると、ループから抜け出すことはありません。また、誰もが問題を抱えているように見える nextInt() の問題につまずいているとは思いません。クラス全体のコードを以下に掲載します。

import java.util.Scanner;
import controller.Controller;
public class TUI {
    private Controller controller;
    public TUI() {
        Controller controller = new Controller();
        this.controller = controller;
    }

    public void run() {
        boolean wantToQuit = false;
        char userInput = 0;
        System.out.println("Welcome to the Mart.");
        do{
            userInput = mainMenu();
            if(isUserInputValid(userInput))
                switch(userInput){
                    case 'a': addItem();
                    break;
                    case 'r': controller.removeItem();
                    break;
                    case 'i': controller.printInventory();
                    break;
                    case 'p': controller.customerPurchase();
                    break;
                    case 'w': controller.weeklyStock();
                    break;
                    case 'c': wantToQuit = true;
                    break;
                }
            else System.out.println("\nMainMenu");



        } while(!(wantToQuit));
        System.out.println("WolfMart is now closed.  Thank you and good-bye.");
    }




    private boolean isUserInputValid(char userInput) {
        char[] testSet = {'a', 'r', 'i', 'p', 'c', 'w'};
        for(char currentChar : testSet) {
            if(currentChar == userInput)
                return true;
        }
        return false;
    }

    private char mainMenu() {
        System.out.println();
        controller.printInventory();
        String mainMenuSelection = "What would you like to do: (a)dd item, (r)emove item, print (i)nventory, " +
            "(p)urchase by customer, (c)lose store?\r\n";

        char mainMenuInput = getUserChar(mainMenuSelection);
        return mainMenuInput;
    }

    private char getUserChar(String prompt) {
        try {
            Scanner scan = new Scanner(System.in);
            System.out.print(prompt);
            String tempString = "";
            tempString = scan.nextLine();
            scan.close();
            char userChar = tempString.charAt(0);
            return userChar;
        } catch(Exception ex) {
            System.out.println(ex.getMessage());
        }
        return 0;
    }


    private int getUserInt(String prompt) {
        Scanner scan = new Scanner(System.in);
        int userInt = -1;
        try {
            System.out.print(prompt);
            String input = scan.nextLine();
            userInt = Integer.parseInt(input);
        }
        catch(NumberFormatException nfe) {
            System.out.println("I did not recognize your command, please try again.");
        }
        scan.close();
        return userInt;
    }

    private String getUserString(String prompt) {
        Scanner scan = new Scanner(System.in);
        String userString = null;
        try{
            System.out.print(prompt);
            userString = scan.nextLine();
        } catch(Exception ex)
        {
            System.out.println("I did not recognize your command, please try again.");
        }
        scan.close();
        return userString;
    }

    private double getUserDouble(String prompt) {
        Scanner scan = new Scanner(System.in);
        double userDouble = -1.0;
        try {
            System.out.print(prompt);
            String input = scan.nextLine();
            userDouble = Double.parseDouble(input);
        }
        catch(NumberFormatException nfe) {
            System.out.println("I did not recognize your command, please try again.");
        }
        scan.close();
        return userDouble;
    }

    private void addItem() {
        String itemName = "";
        double price;
        int quantity;
        String namePrompt = "Enter the name of the item being added to the inventory: ";
        String pricePrompt = "Enter the cost of " + itemName + ": ";
        String quantityPrompt = "Enter the quantity of " + itemName + ": ";
        itemName = getUserString(namePrompt);
        price = getUserDouble(pricePrompt);
        quantity = getUserInt(quantityPrompt);
        controller.addItem(itemName, quantity, price);
    }




}
4

2 に答える 2

9

私のコメントで述べたように、問題はあなたがこのようなことをするたびにあなたが閉じSystem.inているということです:

Scanner scan = new Scanner(System.in);
...
scan.close();

さて、の仕様を見てくださいScanner.nextLine

スロー

  • NoSuchElementException-行が見つからなかった場合
  • IllegalStateException-このスキャナーが閉じている場合

これで、スキャナー自体が閉じられていないため、IllegalStateExceptionがスローされることはありません。代わりに、前に述べたように、「通常は新しい行が見つからないことに関連する」という他の例外NoSuchElementExceptionがスローされます。

これをJDK7を使用していると仮定すると、以下を調べることでこれがどのように機能するかを確認できますScanner.throwFor

if ((sourceClosed) && (position == buf.limit()))
    throw new NoSuchElementException();

例外がスローされるため、の値が0によって返されgetUserCharrunループで使用されます。

    do {
        userInput = mainMenu();
        if (isUserInputValid(userInput)) {
            ...
        } else {
            System.out.println("\nMainMenu");
        }
    } while (!wantToQuit);

入力が無効であるため、ループ印刷に巻き込まれます"\nMainMenu\n"

問題を修正するには、シングルを使用してScanner閉じないでくださいSystem.in;-)

于 2012-08-25T19:16:46.163 に答える
0

を閉じないでくださいScanner

scan.close();    // Don't do it.

それを行うと、問題が発生します。

于 2012-08-26T06:39:30.427 に答える