在学习Java编程的时候,练习了求对数并验证输入,然后出现了一个问题,希望友友们解答一下
先附上代码:
import java.util.Scanner;
public class Work4 {
/**
* 求对数并验证输入
*/
public static void printLogarithm(double num) {
if (num < 0) {
System.out.println(num + " 小于 0,没有对数");
return;
} else if (num ==0) {
System.out.println("0 没有对数");
return;
}
double Logarithm = Math.log(num);
System.out.println(num + " 的对数是:" + Logarithm);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("请输入一个数字:");
// double num = in.nextDouble(); // 【1】
// 验证输入,hasNextDouble 用于检查能否将输入流中的下一个标记转换为 double 值
if (!in.hasNextDouble()) {
String word = in.next();
System.err.println(word + " 不是一个数字");
return; // 结束 if 条件语句
}
double num = in.nextDouble(); // 【2】
printLogarithm(num);
}
}
如上,如果我的
double num = in.nextDouble();
这条语句在【1】这个位置的话,就需要输入两次,而在【2】位置只需要一次,这是为什么呢
下图是在【1】的位置的输出:
下图是在【2】的位置的输出:
该回答引用GPTᴼᴾᴱᴺᴬᴵ
这是因为在代码中先进行了验证输入的操作:
if (!in.hasNextDouble()) {
String word = in.next();
System.err.println(word + " 不是一个数字");
return;
}
这个语句会检查是否有下一个 double 类型的输入,如果没有,则会提示用户输入的不是数字,并且直接结束程序。
·
如果你把这段代码放在了 double num = in.nextDouble(); 之前,程序会在执行 num = in.nextDouble(); 时直接跳过,因为之前的检查已经将输入流中的非 double 类型的输入消耗掉了,所以需要再次输入。
·
而如果你把这段代码放在了 double num = in.nextDouble(); 之后,因为这时候已经确定输入流中存在一个 double 类型的输入,所以不需要再次输入。
首先需要把控制台缓冲区清空下,然后才能读取你的数字
参考GPT和自己的思路:
问题的原因在于 Scanner 类中的 nextDouble() 方法会读取输入流中的下一个 double 类型的标记,如果输入流中的下一个标记不是 double 类型的话,方法就会抛出 InputMismatchException 异常。而在 【1】位置执行了 hasNextDouble() 方法检查输入流中下一个标记的类型,此时输入流中可能已经包含了一个非 double 类型的标记,导致 nextDouble() 方法在执行时不能正常读取输入流中的下一个 double 类型的标记,从而需要再手动输入一次,而在 【2】位置则没有执行 hasNextDouble() 方法,此时 nextDouble() 方法是直接读取输入流中的下一个 double 类型的标记,不会出现错误,因此只需要输入一次即可。因此,如果要在输入之前进行类型检查,应该放在输入语句之前,如下所示:
Scanner in = new Scanner(System.in);
System.out.print("请输入一个数字:");
if (in.hasNextDouble()) { // 在输入之前进行类型检查
double num = in.nextDouble();
printLogarithm(num);
} else {
String word = in.next();
System.err.println(word + " 不是一个数字");
}