我正在尝试下面的代码,但我得到了无限循环。断点似乎没有任何帮助。
import java.util.Scanner;
public class Question2 {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter ID Number: ");
int studentSn = keyboard.nextInt();
System.out.print("Enter your Marks: ");
int Score = keyboard.nextInt();
Scanner scan = new Scanner(System.in);
boolean stop = false;
String answer = "";
String Grade = "";
String msg = "";
int counter = 0;
while (!stop) {
if (Score < 50) {
Grade = "F";
} else if (Score <= 64) {
Grade = "P";
} else if (Score <= 74) {
Grade = "C";
} else if (Score <= 84) {
Grade = "D";
} else if (Score <= 100) {
Grade = "HD";
} else {
msg = "Invalid Input";
}
if (Grade != null) {
System.out.println("Student Serial Number: " + studentSn);
System.out.println("Your Grade is: " + Grade);
System.out.println("Do you want to continue (yes/no): " + answer);
} else {
System.out.println("Student Serial Number: " + studentSn);
System.out.println(msg);
System.out.println("Do you want to continue (yes/no): " + answer);
}
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
}
}
}
}
答案 0 :(得分:4)
在这种情况下有多个无限循环。与
while (!stop) {
// ...
}
你永远不会设置&#34;停止&#34;为true,意味着循环结束。
中的break语句while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
}
只会突破该循环,而不是!stop
循环。如果你想要摆脱两个循环,你需要做
MY_LABEL: while (!stop) {
// ...
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break MY_LABEL;
}
}
或以其他方式写stop = true;
。但是,这不是代码中唯一无限循环。在
while (answer.equalsIgnoreCase("YES"));
{
// loop body ^ problem here
}
你的循环语句后面跟着一个分号!这应该是
while (answer.equalsIgnoreCase("YES"))
{
// loop body
}
因为您的代码现在与编写
相同while (answer.equalsIgnoreCase("YES"))
; // do nothing
// loop body
因为Java的语法是如何工作的。您当前的代码编译是因为您可以拥有一个没有任何循环或if语句的块
// do some stuff
{ // begin new scope
int x = 10;
} // end scope
int y = x; // error because x is not in scope!
但这显然不是你想要的。
除此之外,你永远不会读到answer
中的任何内容,这意味着它总是等于""
- 它永远不等于&#34;是&#34;或&#34;否&#34;一点都没有!至少在某处你应该说
answer = scan.nextLine();
阅读输入。
整个节目虽然有点不稳定。以下是我的说法:
// Instead of using "stop", we can just break out of the loop when we're done
while(true) {
// ...
// Prompt for input. I use "print" instead of "println" so that the user's answer will be on the same line as the question, e.g.
// Do you want to continue (yes/no): YES
// instead of
// Do you want to continue (yes/no):
// YES
// and so forth
System.out.print("Do you want to continue (yes/no): ");
// This is how we actually read input.
String answer = scan.nextLine();
// If the user doesn't say "YES" (this could be "NO" or "q" or "asdf" or anything else), break out of the loop
if(!answer.equalsIgnoreCase("YES"))
break;
}
我认为您对循环和输入的工作方式有点困惑。仅仅因为您编写System.out.println("my question: " + answer)
并不意味着Java会将该行的其余部分读入answer
。它实际上会写出answer
中已有的内容,例如
answer = "abc"
System.out.println("Question? " + answer);
// "Question? abc" will be printed, and no input will be read
// answer still equals "abc"
另外,如果你想反复提问,你必须把所有的问题都放到循环中。在answer
再次readLine()
之前,Java不会读到answer.equalsIgnoreCase("YES")
中的任何新内容,所以我认为有关while循环的混淆来自于此。在answer = scan.readLine()
循环中,除非您将grep -oP "\^I" $1 | wc -l
放入其中,否则不会读取任何新内容。
答案 1 :(得分:0)
你有两个while循环,你的破坏尝试没有正确执行,只是退出内循环。
让你的循环逻辑剥离回来只描述会影响循环本身的变量和逻辑:我已经用方法调用替换了你的其他代码来简化演示,假设你已经实现了这些方法并且他们做了什么名字推断。
这是一种很好的技术,用于将伪代码转换为实际代码,但同样有助于评估不按照您计划的方式进行的循环结构
int studentSn = ReadInt("Enter ID Number: ");
int Score = ReadInt("Enter your Marks: ");
string answer = "";
boolean stop = false;
while(!stop) { // this is never ending, nothing ever sets stop to true
Grade = DetermineGrade(score);
if (Grade != null) {
ShowGrade(studentSn, Grade);
answer = ReadContinuePrompt();
} else {
ShowError(studentSn, "Invalid Input");
answer = ReadContinuePrompt();
}
while (answer.equalsIgnoreCase("YES"));
{
counter++;
if (answer.equalsIgnoreCase("NO")) {
break;
}
// If this user's input was not NO, then this loop is infinite and should run into a stack overflow error when the value of counter exceeds the max value of int
}
}
您的外循环基于一个停止变量:
while (!stop)
因此,在循环逻辑中,您需要做的就是将stop的值设置为true,而不是使用break语句。精心设置的break语句也可以这样做,但是按照你的方式编写一个有意识的停止参数是一个很好的设计,使意图非常清晰。
现在你的内循环是错误的,我不想过度分析它,因为你要求循环外的用户输入,没有办法改变答案。所以让我们用一个简单的条件语句替换内部循环
if(answer.equalsIgnoreCase("NO"))
stop = true; // or break;
else
counter++;
现在我们需要回到你编写外循环的方式。同样,因为主要输入在循环之外,所以我们可以说这个代码没有多少时间可以说&#34;是&#34;这将给出不同的答案,我们需要在循环内询问分数输入,以便可以更改结果
现在给了我们这个逻辑:
int studentSn = ReadInt("Enter ID Number: ");
string answer = "";
boolean stop = false;
while(!stop) {
// read the score inside the loop.
int Score = ReadInt("Enter your Marks: ");
Grade = DetermineGrade(score);
if (Grade != null) {
ShowGrade(studentSn, Grade);
answer = ReadContinuePrompt();
} else {
ShowError(studentSn, "Invalid Input");
answer = ReadContinuePrompt();
}
if(answer.equalsIgnoreCase("NO"))
stop = true; // or break;
else
counter++;
}