为什么此扫描程序将null分配给变量? [英] Why is this Scanner assigning null to a variable?

查看:92
本文介绍了为什么此扫描程序将null分配给变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要进行大学评估,我必须使用具有类级别范围的称为sc的扫描仪,并且整个程序必须包含在一个类中.主要方法调用menu()方法,该方法使用Scanner和for循环来响应用户输入而调用两种方法之一.

For a college assessment I'm having to use a Scanner called sc with a class-level scope, and the entirety of the program has to be contained in a single class. The main method calls a menu() method, which uses the Scanner and a for loop to call one of two methods in response to user input.

这两种方法之一使用扫描仪来计算输入整数的阶乘.一旦执行了该方法,menu()中的for循环就会继续.为了避免由于用户输入浮点数而导致InputMismatchException,我使用了try/catch.但是,当程序返回到menu()进行循环时,扫描器在分配给choice时会导致InputMismatchException.如何让Scanner提示用户再次输入?抱歉,如果我缺少明显的内容,这是我学习过的第一门编程语言.这应该是精简的可编译代码:

One of the two methods uses the Scanner to calculate the factorial of an input integer. Once the method is executed, the for loop in menu() continues. To avoid an InputMismatchException due to the user entering a float, I used try/catch. However when the program returns back to the menu() for loop the Scanner causes an InputMismatchException when assigning to choice. How can I get Scanner to prompt the user for input again? Apologies if I'm missing something obvious, this is the first programming language I've ever learned. This should be the stripped down compilable code:

package summativeassessment;

import java.util.InputMismatchException;
import java.util.Scanner;

public class SummativeAssessment {

    private static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        menu();
    }

    public static void menu(){
        String fName;
        String sName;

        System.out.print("Enter your first name: ");
        fName = sc.next();
        System.out.print("Enter your last name: ");
        sName = sc.next();

        try{
            for(int choice = 1; choice!=0;){
              System.out.print("Option 1 to generate username. Option 2 to calculate factorial. Press 0 to quit: ");
              choice = sc.nextInt();
              switch(choice){
                  case 2:
                      System.out.println(fName+" "+sName+", you have selected option 2");
                      numberFactorial();
                      break;
                  case 0:
                      break;
                  default:
                      System.out.println("Invalid option. Please try again.");
              }
            }
        } catch(InputMismatchException ex){
            String msg = ex.getMessage();
            System.out.println(msg);
        }
    }

    public static void numberFactorial(){
        System.out.print("Enter a number: ");
        try{
            int numIn = sc.nextInt();
            long result = numIn;
            if(numIn>0){

                for(int factor = 1; factor<numIn; factor++){
                    result *= factor;
                    if(factor==numIn-1){
                        System.out.println("The factorial is "+result);
                    }
                }
            }
            else{
                System.out.println("Enter a positive integer greater than 0");
            }
        }
        catch(InputMismatchException ex){
            System.out.println("Input invalid");
        }
    }
}

推荐答案

我调试了您的代码,并得到了以下结果:

I debugged your code and got this result:

如果输入浮点数作为输入,则会触发InputMismatchException,但缓冲区中仍然有内容.因此,下次调用sc.nextInt()时,它不会等到您输入值,因为缓冲区中已经有东西,因此它将下一个值从缓冲区中取出,并尝试将其解释为整数.但是,它不能这样做,因为它不是整数,所以再次引发InputMismatchException并被捕获在菜单的catch中,从而导致程序退出.

If you enter a float as input you trigger the InputMismatchException but there is still something in your buffer. So the next time sc.nextInt() is called, it won't wait until you input a value because something is in the buffer already, so it takes the next value out of the buffer and tries to interpret is as an integer. However, it fails to do so, because it is not an integer, so an InputMismatchException is raised again and caught in your menu's catch, now leading to the exit of the program.

解决方案是在第一次引发异常后绘制缓冲区中剩余的任何内容.

The solution is to draw whatever is left in the buffer after the exception was raised the first time.

因此,工作代码将在异常内包含清除sc.next()的缓冲区:

So the working code will contain a buffer clearing sc.next() inside the exception:

    public static void numberFactorial(){
    System.out.print("Enter a number: ");
    try{
        int numIn = sc.nextInt();
        long result = numIn;
        if(numIn>0){

            for(int factor = 1; factor<numIn; factor++){
                result *= factor;
                if(factor==numIn-1){
                    System.out.println("The factorial is "+result);
                }
            }
        }
        else{
            System.out.println("Enter a positive integer greater than 0");
        }
    }
    catch(InputMismatchException ex){
        System.out.println("Input invalid");
        sc.next();
    }
}

这篇关于为什么此扫描程序将null分配给变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆