do-while 循环中的 try-catch 块未正确循环并继承最后一个输入结果

Try-catch blocks within do-while loops are not looping properly and carrying over the last input result

提问人:learningtoc0d3 提问时间:10/30/2020 最后编辑:learningtoc0d3 更新时间:10/30/2020 访问量:56

问:

Scanner scan = new Scanner(System.in);   
        int year = -1;
        int yearDuplicate = -1;
        System.out.println("This calculator tells you whether a year that you "
                + "enter is a leap year.\nPlease enter a year:");
        
        do{
            try{
                year = scan.nextInt();
            }catch(Exception e){
                System.out.println("ERROR. Please enter a numerical digit "
                        + "without decimals:");
                scan.next();
            }    
            
        }while(year % 1 != 0);
            
        
        do{
            if(yearDuplicate % 4 == 0){ 
                if(yearDuplicate % 100 == 0){
                    if(yearDuplicate % 400 == 0){
                        System.out.println(yearDuplicate + " is a leap year.");
                    }else{
                        System.out.println(yearDuplicate + " is not a leap year.");
                    }
                }else{
                    System.out.println(yearDuplicate + " is a leap year.");
                }
            }else{
                System.out.println(yearDuplicate + " is not a leap year.");
            }
            
            System.out.println("Enter another year or enter '-1' to quit:");
            try{
                yearDuplicate = scan.nextInt();
            }catch(Exception e){
                System.out.println("ERROR. Please enter a numerical digit "
                        + "without decimals:");
                scan.next();
            }
            
        }while(yearDuplicate != -1);

我正在尝试制作一个闰年计算器,该计算器还可以告诉您是否不小心输入了字符串或双精度而不是整数。我希望这个程序做的是运行“错误。请一遍又一遍地输入一个没有小数的数字:“,直到用户输入一个整数。但是,目前,对于第一次尝试捕获块,如果我输入了两个错误的输入类型,它会给我以下错误消息:

test
ERROR. Please enter a numerical digit without decimals:
-1 is not a leap year.
Enter another year or enter '-1' to quit:
test
ERROR. Please enter a numerical digit without decimals:
BUILD SUCCESSFUL

第二个至少稍微好一点,它不断重复我输入的最后一个整数的结果(年份“是/不是闰年”),但至少它永远重复,不像第一个。

test
ERROR. Please enter a numerical digit without decimals:
10 is not a leap year.
Enter another year or enter '-1' to quit:
test
ERROR. Please enter a numerical digit without decimals:
10 is not a leap year.
Enter another year or enter '-1' to quit:

我想要的所有错误消息都会被重播,直到您输入正确的数字。如何摆脱之前的输入结果,以及如何解决第一次尝试捕获块只运行两次的事实?

我在网上看了看,但似乎如果我更改了这个程序的一小部分,其他东西就会坏掉。如果我将第一个 while 循环的条件设为 while(year % 1 == 0),它完全符合我的要求;但这意味着如果它是一个整数,while 循环会重复,这与我希望它做的事情完全相反。如果我搞砸了scan.next();,它会给我一个无限的错误循环。

顺便说一句,有两个尝试捕获块,因为用户在一年内有两个机会进入,并且有两个地方我可能需要纠正它们。如果我把它们都放在同一个 while 循环中,它会在第一次起作用,但在那之后,每次我都需要输入两个数字(一个用于第一次尝试捕获,被第二次尝试捕获覆盖)。

编辑:我将 year 和 yearDuplicate 的起始值更改为 0,在 try catch 块内声明扫描仪并删除了 scan.next();在这两个尝试中,捕获块。现在,我得到了一个循环,第一次尝试捕获块,但它仍然继承了我之前的输入。

java try-catch java.util.scanner do-while

评论

0赞 user14387228 10/30/2020
你想象的效果是什么?year % 1 != 0

答:

1赞 user14387228 10/30/2020 #1

您的基本“读取直到得到整数”块应如下所示:

    do {
        try {
            year = scan.nextInt();
            if (year <= 0) { // see comment
                System.out.println("ERROR. Please enter positive number");
            }
        } catch(Exception e){
            System.out.println("ERROR. Please enter a number "
                               + "without decimals");
            scan.next();
            year = -1;
        }                
    } while (year <= 0);

因此,如果存在非数字输入,则主动设置一个将导致循环的值,而不是依赖于可能已经存在的内容。

此外,您还需要确保输入为正数。

鉴于您应该能够弄清楚整个程序。

在我说“看到评论”的地方,也许你可能想检查一个合理的年份;也许在 1752 年左右(当时英国和美国采用公历)之前扔掉任何东西。

您最初的问题可能是由于这种情况造成的。这意味着“当年除以 1 时的余数不是 0”。对于非负值,这始终是正确的。在这种情况下,我必须查找 Java 如何实现负值才能回答。year % 1 != 0%

评论

0赞 learningtoc0d3 10/30/2020
好的,首先,看起来我对尝试捕捉块的理解有点偏离。我以为它们会自己循环或其他东西(这是有道理的,为什么在原始情况下,它会在给我异常错误之前进行所有计算)。另外,'scan.next();' 是否与 'year = -1;' 做同样的事情,它会导致你循环而不是 Java 给你一个错误,即存在输入不匹配?
0赞 user14387228 10/30/2020
re: scan.next() -- 输入流中有一些令牌;scan.nextInt() 是不可接受的。nextInt 的文档说,它只有在成功转换整数时才会推进输入,因此在失败的情况下,您需要调用 next() 以“通过”不是整数的标记。
0赞 learningtoc0d3 10/30/2020 #2

修复了代码。

int year = 0;
        int yearDuplicate = 0;
        System.out.println("This calculator tells you whether a year that you "
                + "enter is a leap year.\nPlease enter a year:");
        
        do{
            Scanner scan = new Scanner(System.in);
            try{
                yearDuplicate = scan.nextInt();
                if(yearDuplicate % 4 == 0){ 
                    if(yearDuplicate % 100 == 0){
                        if(yearDuplicate % 400 == 0){
                            System.out.println(yearDuplicate + " is a leap year.");
                        }else{
                            System.out.println(yearDuplicate + " is not a leap year.");
                        }
                    }else{
                        System.out.println(yearDuplicate + " is a leap year.");
                    }
                }else{
                    System.out.println(yearDuplicate + " is not a leap year.");
                }
                System.out.println("Enter another year or enter '-1' to quit:");  
                
            }catch(Exception e){
                System.out.println("ERROR. Please enter a numerical digit "
                        + "without decimals:");
                scan.next();
            }
            
        }while(yearDuplicate != -1);

基本上删除了第一次尝试捕获块。使第二个 try catch 块包含整个 do while 循环。如果有人知道我以前犯过什么错误以及为什么他们错了,我仍然想知道。