Scanner类的使用笔记

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值