Java 验证有问题:即使逻辑看起来很好,也会出现无限循环
我正在做这个“餐厅”项目,它需要两个输入:账单金额和1到3的满意度水平。我尝试使用hasNextDouble()验证每个输出,但由于某种原因,当我运行程序时,第一个if语句中的else语句无限运行。谁能看看这个吗Java 验证有问题:即使逻辑看起来很好,也会出现无限循环,java,while-loop,java.util.scanner,Java,While Loop,Java.util.scanner,我正在做这个“餐厅”项目,它需要两个输入:账单金额和1到3的满意度水平。我尝试使用hasNextDouble()验证每个输出,但由于某种原因,当我运行程序时,第一个if语句中的else语句无限运行。谁能看看这个吗 package tips; import java.util.Scanner; public class Tips { public static void main(String[] args) { /* Ask for the diners’ satisfaction
package tips;
import java.util.Scanner;
public class Tips {
public static void main(String[] args) {
/* Ask for the diners’ satisfaction level using these ratings:
1 = Totally satisfied, 2 = Satisfied, 3 = Dissatisfied.
If the diner is totally satisfied, calculate a 20 percent tip.
If the diner is satisfied, calculate a 15 percent tip.
If the diner is dissatisfied, calculate a 10 percent tip.
Report the satisfaction level and tip in dollars and cents.*/
Scanner in = new Scanner(System.in);
boolean isDouble = false;
boolean isInt = false;
TipsCalculator tips = new TipsCalculator();
while (!isDouble && !isInt) {
System.out.print("Please enter the bill amount: ");
//Checks if the input is a double.
if(in.hasNextDouble()) {
tips.setBill(in.nextDouble());
isDouble = true;
} else {
System.out.println("The value entered is not a valid amount.");
continue;
}
System.out.println("Please enter your satisfaction level: \n1 = Totally Satisfied.\n2 = Satisfied.\n3 = Dissatisfied.");
//Checks if the input is an integer.
if(in.hasNextInt()) {
tips.setSatisfactionLevel(in.nextInt());
isInt = true;
//Prints different outputs depending on the satisfaction level.
if (tips.getSatisfactionLevel() == 1) {
System.out.println("You are totally satisfied! :-)" +
". \n" +
"Your tip amount is: " +
tips.calculateTips());
} else if (tips.getSatisfactionLevel() == 2){
System.out.println("You are satisfied! :-)" +
". \n" +
"Your tip amount is: " +
tips.calculateTips());
} else if (tips.getSatisfactionLevel() == 3) {
System.out.println("You are dissatisfied! :-(" +
". \n" +
"Your tip amount is: " +
tips.calculateTips());
} else {
//Error if the level is not from 1 to 3.
System.out.println("The value entered is not between 1 and 3");
}
} else {
System.out.println("The value entered is not between 1 and 3");
continue;
}
} in.close();
}
}
isDoubl
和isInt
都是假的,所以!是双重的&!isInt
将始终为真。这是无限循环背后的根本原因。不要将输入读取为double和int。将其读取为字符串,然后在代码中将其解析为double或Integer。在Integer和Double类中使用方法valueOf(String)。要分析字符串,无限循环的原因是:
Scanner中的hasNextDouble方法类内部调用hasNext方法。
它是这样写的
public boolean hasNext(Pattern pattern) {
ensureOpen();
if (pattern == null)
throw new NullPointerException();
hasNextPattern = null;
saveState();
while (true) {
if (getCompleteTokenInBuffer(pattern) != null) {
matchValid = true;
cacheResult();
return revertState(true);
}
if (needInput)
readInput();
else
return revertState(false);
}
}
在上面的方法中,getCompleteTokeinBuffer方法调用才是真正的罪魁祸首。此getCompleteTokenInBuffer可以返回以下3种可能性
/*
* 1. valid string means it was found
* 2. null with needInput=false means we won't ever find it
* 3. null with needInput=true means try again after readInput
*/
在hasNextmthod中,每当我们第一次输入非双精度值时,我们将能够读取数据,getCompleteTokeinBuffer将返回null,并将第一次设置needInput=false。但是,第二次,hasNext方法将返回值false,因为needInput=false条件将为true
此needInput=false条件将在随后的hasNextDouble方法调用中保持为true。由于这个原因,我们无法读取任何数据,这导致了无限循环。噢,当我输入一个十进制数字时会出现错误,如:39.4如果您不在美国,您可能需要在.useLocale(locale.US)中设置区域设置;如果我输入39,它工作正常……那没有意义-!操作员不是这样吗!如果isDouble设置为false,则isDouble为true。允许用户自己为您提供输入、解析和验证是一种更好的做法。因此,您将输入作为原始数据读取,然后才对其进行验证。