文章目录
1 Scanner的hasNext()
import java.util.Scanner;
public class TestScanner1 {
public static void main(String[] args) {
System.out.println("请输入若干单词,以空格作为分隔");
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
System.out.println("键盘输入的内容是:" + sc.next());
}
System.out.println("while循环结束");
}
}
结果:一直等待输入,因为while循环没有结束。证明hasNext()一直是true
import java.util.Scanner;
public class TestScanner1 {
public static void main(String[] args) {
System.out.println("请输入若干单词,以空格作为分隔");
Scanner sc = new Scanner(System.in);
while (!sc.hasNext("#")) // 匹配 # 返回true,然后取非运算。即以#为结束符号,且不能是 #串 如 a# ##
{
System.out.println("键盘输入的内容是:"+ sc.next());
}
System.out.println("while循环结束");
}
}
遇见字符 # 就会结束循环
引用:https://blog.csdn.net/gao_zhennan/article/details/80562548
2.Scanner的nextInt()输入字符串用异常try之后不让再次输入的问题
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
try {
System.out.println("请输入数字:");
int input = sc.nextInt();
break;
} catch (InputMismatchException e) {
System.out.println(e.getMessage());
}
}
}
这段代码如果输入字符,会陷入死循环
2.1分析:
scanner在要求用户输入的时候,其实是在内存中创建了一段内存A
用于用户输入,输入的数据就会存入该段内存。然后通过nextInt()方法以依次获取存入的数据(个人理解:类似于集合的迭代器遍历,但是他获取到之后可能会多一个清空内存A
区域的步骤),那么问题就来了,当我们输入字符串的时候,nextInt()并不能获取到字符串类型的数据,就导致了指针一直在字符串哪里,然后输入的字符串一直在内存A
里,在while循环时,一直发现有元素,但是取不出来,就进入死循环。
ps:A
只是个别名,方便看
2.2简单来说就是:
nextInt()只能扫描下一个int类型数据,返回下一个标记,输入"字符串"用nextInt()扫描不到,自然也不会返回下一个标记,就会无限循环。
同理,nextInt()也获取不到double类型,nextDouble()的时候,可以输入int,因为int向上转型是自已自动转的。但是nextDouble获取不到字符串。
可是nextLine和next就不一样了,他们都是字符串类型,所有数字都可以当做字符串类型啊。但是要注意,nextLine()遇见换行符就结束了。所以要用next()。
2.3解决办法:
1.每次循环都创建一个新的Scanner对象,但是占用堆内存较多,不推荐。
2.在catch的时候,调用next(),不能用nextLine(),原因看next和nextLine区别,获取当前非法数据的标记,可以让当前对象清空内存。使当前scanner对象可以继续扫描输入数据。
2.3.1实验:
1.验证刚才的说法,double转int,大转小,强转。所以nextInt(),肯定不能获取double类型的值,那么,在catch里加一个 nextDouble(),肯定就可以顺利把double的值拿出来,清空输入内存A
。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
try {
System.out.println("请输入数字:");
int input = sc.nextInt();
System.out.println(input);
break;
} catch (InputMismatchException e) {
// sc.nextLine();
sc.nextDouble();
System.out.println("只能输入整形数字类型");
}
}
}
结果:果然没错。。。。
实验二:
nextLine()肯定能获取到所有类型的数据,那么只要有数据异常,肯定可以把内存中占用的数据取出来。所以nextLine()应该是万能的。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
try {
System.out.println("请输入数字:");
int input = sc.nextInt();
System.out.println(input);
break;
} catch (InputMismatchException e) {
sc.nextLine();
System.out.println("只能输入整形数字类型");
}
}
}
结果:基本上没问题。不排除没有想到的类型。
3.自用工具类
package day15.work.stumanage;
import java.util.Scanner;
public class ScannerUtil {
public static Scanner scanner = new Scanner(System.in);
private static String readKeyBoard(int limit) {
String line = "";
while (scanner.hasNext()) {
line = scanner.nextLine();
if (line.length() < 1 || line.length() > limit) {
System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
/**
* 开始菜单输入
* @return
*/
public static char readMenuSelection() {
char c;
for (;;) {
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != '1' && c != '2' && c != '3' && c != '4' && c != '5') {
System.out.println("输入错误请重新输入:");
} else {
break;
}
}
return c;
}
/**
* 查询菜单输入
* @return
*/
public static char readMenuSelection2() {
char c;
for (;;) {
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c!='0') {
System.out.println("输入错误请重新输入:");
} else {
break;
}
}
return c;
}
/*
* 输入三位数以内的数,年龄
*/
public static int readNumber() {
int n;
for (;;) {
String str = readKeyBoard(3);
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.println("数字输入错误,请重新输入");
}
}
return n;
}
/**
* 获取Y/N y/n
*/
public static char readConfirmSelection() {
char c;
for (;;) {
String str = readKeyBoard(1).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.println("输入有误,请重新输入:");
}
}
return c;
}
public static String readString() {
String str = readKeyBoard(16);
return str;
}
}
next()和nextLine()区别
next() 遇到空白分隔符就中断,返回的字符串不支持中间有空格的。
nextLine() 如果中间有空格的字符串,需要通过该方法返回。
注意: next/nextInt/nextDouble方法与nextLine方法不能连用,
如果必须要连用,需要重新创建一个Scanner对象。
4注意: 为什么nextLine不能放在next(),newxtInt…等后面?
https://blog.csdn.net/guanghuichenshao/article/details/81545450