简体   繁体   English

如果突破内部if,为什么我的消息打印两次?

[英]Why is my message printing twice when I break out of the inner if?

I am having a little problem with my code. 我的代码有一点问题。 Compiling and running works well, however, when I attempt to break out of the inner loop, 编译和运行效果很好,但是,当我尝试突破内循环时,

System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");

The code above is printing twice to the terminal when I only want it to print once. 当我只希望它打印一次时,上面的代码将两次打印到终端。

I have a feeling that is a simple mistake with the way my brackets are aligned but I am having difficulty with figuring out how to do it. 我感觉这是我的括号对齐方式的一个简单错误,但是我很难弄清楚该如何做。 Any help would be greatly appreciated! 任何帮助将不胜感激!

import java.util.Scanner;

public class GetGrade {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        final int MAX = 15;

        int[] homework = new int[MAX];
        int[] classwork = new int[MAX];
        int[] lab = new int[MAX];
        int[] test = new int[MAX];
        int[] quizzes = new int[MAX];
        int[] midterm = new int[MAX];
        int[] fin = new int[MAX];
        int hwCount, clCount, labCount, testCount, quizCount, midCount, finCount;
        double hwTotal, clTotal, labTotal, testTotal, quizTotal, midTotal, finTotal;
        double grade = 0;

        String selection = "";

        System.out.println();
        System.out.println("Welcome to GetGrade!");
        System.out.println();

        while (true) {

            System.out.println("Type which category you want to add to.");
            System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
            selection = input.nextLine();

            if (selection.equals("homework")) {

                System.out.print("What percentange of your grade is homework? > ");
                double hwPercent = input.nextDouble();
                System.out.println("Now begin typing your grades. When you are finished, type -1.");

                for (int i = 0; i < homework.length; i++) {
                    homework[i] = input.nextInt();
                    hwTotal = homework[i] * hwPercent;
                    grade += hwTotal;
                    if (homework[i] == -1) break;
                }
            }
        }
    }
}

It's just as trivial as it seems: 它看起来很简单:
The call to input.nextInt(); 调用input.nextInt(); in your inner loop does not include the newline. 在您的内部循环中不包括换行符。 So you are breaking of the innerloop, receiving the next line which only contains the newline - character in input.nextLine(); 因此,您正在破坏内部循环,接收仅包含换行符的下一行-input.nextLine();中的字符; which is the remaining input of your "-1\\n" line and proceed with the main loop again as it does not match "homework". 这是您的“ -1 \\ n”行的其余输入,并由于与“作业”不匹配而再次进入主循环。

Try setting the conditional variable in your while loop to an actual boolean rather than true. 尝试将while循环中的条件变量设置为实际的布尔值,而不是true。

Also, when you invoke "break", you are only breaking out of the for loop. 同样,当您调用“ break”时,您只会脱离for循环。 If you reassign a boolean variable to false at this point, you would exit the while loop completely. 如果此时将布尔变量重新分配为false,则将完全退出while循环。

Just before while loop ends, add a "Do you want to continue? (Y/N)" functionality. 在while循环结束之前,添加“是否要继续?(是/否)”功能。

If user enters "N" or anything else, execute another break. 如果用户输入“ N”或其他,则执行另一个中断。 And that break will make you get out of the while loop. 这种中断将使您摆脱while循环。

The simple way to get your code working is to change 使代码正常工作的简单方法是更改

selection = input.nextLine();

to

selection = input.next();

next() only reads in a string value (which is what you are actually doing in your code) instead of the newline character as Peter has suggested. next()仅读取字符串值(这是您在代码中实际执行的操作),而不是彼得建议的newline

So the an extra iteration of the while does not take place when you read the newline character. 因此,当您读取newline时,while的额外迭代不会发生。

When you use a scanner to read a line from the keyboard, it reads everything up to and including the newline character the user types to submit their input. 当您使用扫描仪从键盘上读取一行时,它会读取用户键入并提交其输入之前的所有内容,包括换行符。 So for example: 因此,例如:

Type which category you want to add to.
Homework, Classwork, Labs, Test, Quizzes, Midterm, Final
>

If you type "homework" and then ENTER, the actual input becomes "homework\\n". 如果键入“ homework”,然后按Enter,则实际输入将变为“ homework \\ n”。 input.nextLine() will scan the input until it encounters the first newline character, '\\n', which it will consume and then it returns everything up to that point (ie "homework"). input.nextLine()将扫描输入,直到遇到第一个换行符'\\ n',它将消耗该字符,然后返回到该点为止的所有内容(即“作业”)。

Your problem here is that input.nextInt() does NOT consume a newline character, and so there is still a newline character in the input buffer by the time your while loop starts another round. 您的问题是input.nextInt()不会占用换行符,因此, while循环开始另一回合时,输入缓冲区中仍然存在换行符。

Now begin typing your grades. When you are finished, type -1.
> ...
> -1
      => User input is "-1\n"
-------------------------------

// Meanwhile, back in the code...
for (int i=0;i<homework.length;i++) {
   homework[i] = input.nextInt();      // <--- This call consumes "-1" but leaves '\n'
   hwTotal = homework[i] * hwPercent;
   grade += hwTotal;
   if (homework[i] == -1) break; 
}

That newline is consumed by the next call to input.nextLine() , leaving the input buffer empty. 下一个对input.nextLine()调用将占用该换行符,而输入缓冲区为空。

while (true) {
    System.out.println("Type which category you want to add to.");
    System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
    selection = input.nextLine();    // <--- This call consumes the leftover '\n' and returns the empty string
    ...

And because "" is not equal to "homework", the while loop goes around one more time, but this time the input buffer is empty, and so the call to input.nextLine() behaves as you would expect. 而且,由于“”不等于“作业”,因此while循环又进行了大约input.nextLine() ,但是这次输入缓冲区为空,因此对input.nextLine()的调用的行为与您期望的一样。

// selection is empty, so this condition fails and the program loops back around
if (selection.equals("homework")) {
    ...

There are two easy solutions to this problem. 有两个简单的解决方案。 You can 您可以

  • Use Integer.parseInt(input.nextLine()) instead of input.nextInt() 使用Integer.parseInt(input.nextLine())代替input.nextInt()
  • Add an extra call to input.nextLine() at the end of your while loop to consume the final newline character while循环的结尾添加对input.nextLine()的额外调用以消耗最后的换行符

The first option is probably the most robust, and you get the added benefit of a run-time error being thrown if they do not give you a valid integer as input. 第一个选项可能是最健壮的,如果它们没有给您提供有效的整数作为输入,则会获得运行时错误的额外好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM