Scanner.nextLine()读取不到输入的坑,详细分析原因和解决方法

问题描述

Scanner.next系列的输入读取和Scanner.nextLine()混用时导致读取不到数据。
next nextInt nextDouble nextFloatScanner.nextLine()连用都会有问题。

例如下面(只输入一次就产生了两个输出,产生Scanner.nextLine()被跳过的错觉):

        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt();
        String rs=sc.nextLine();
        System.out.println("a:"+a);
        System.out.println("rs:"+rs);
        //控制台输出  
		//1
		//a:1
		//rs:

问题分析

  • 使用Scanner.next系列的输入读取时,首先读取开始是从有效字符开始的,有效字符前的回车、空格等都不算读取到的内容;当遇到空格、tab、enter回车时,读取结束
  • Scanner.nextLine()的读取是以换行符\r\n(Windows下)结束的。
  • 另外,使用Scanner.next系列读取输入后,换行符(\r\n)是被留在缓存区的,而Scanner.nextLine()读取后,在缓存区的换行符(\r\n)会被清除,这也说明了为什么混合使用Scanner.next系列Scanner.nextLine()会产生读取不到的问题,因为Scanner.next系列读取后,留在缓存区的换行符被下一次的Scanner.nextLine识别到,直接读取结束。
        Scanner sc=new Scanner(System.in);
        String a=sc.next();
        System.out.println("a:"+a);   
        //控制台输入
		// 1234 45  (空格1234空格45)
		//输出 a:1234   (无法读取空格)
		
        String a=sc.next();
        String rs=sc.nextLine();
        System.out.println("a:"+a);
        System.out.println("rs:"+rs);
        //控制台输入
		//1234 45  (1234空格45)
		//输出 a:1234
		//    rs: 45   (rs=空格45  nextLine()是读取到空格了的)

当使用Scanner.next系列(next、 nextInt 、nextDouble 、nextFloat)读取输入时,从缓存区读取数据,如输入了 1234,然后回车换行(\r\n),Scanner.next读取到了1234,但是回车字符(\r\n)被留到了缓存区,再使用Scanner.nextLine()读取数据时,直接返回了换行符(\r\n)前的数据,因此输入为空。

  • 此时再分析上面最开始那个例子,就明白为什么产生了没有输入的现象。
        int a=sc.nextInt();
        String rs=sc.nextLine();
        //缓存区 1换行符(\r\n)
        System.out.println("a:"+a);   //a:1  缓存区还剩回车符
        System.out.println("rs:"+rs); //rs:  识别到换行符,读取结束,输出无

解决方案:

两种解决方案。

  • 一种是最简单的,就是避免使用Scanner.nextLine()Scanner.next系列的混用,导致产生无输入。
  • 另一种是混用时,在使用Scanner.next系列读取输入后,先使用Scanner.nextLine()读取一次,去掉缓存区的换行符,再使用一次Scanner.nextLine()输入想要的字符串。
		//目的:接收到输入123和abc
        Scanner sc=new Scanner(System.in);
        String a=sc.next();
        sc.nextLine();  //去除缓存区的换行符
        String rs=sc.nextLine();
        System.out.println("a:"+a);
        System.out.println("rs:"+rs);
        //控制台:
        //输入             
        //123 
        //abc
        //输出
        //a:123
        //rs:abc
        //使用 变量s 更容易理解 读取不到输入的现象
        Scanner sc=new Scanner(System.in);
        String a=sc.next();
        String s=sc.nextLine();
        String rs=sc.nextLine();
        System.out.println("a:"+a);
        System.out.println("s:"+s);
        System.out.println("rs:"+rs);
        //输入不变,输出
        //a:123 
        //s:
		//rs:abc

查阅官方API文档 nextLine():

public String nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line,excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
Returns: the line that was skipped Throws:
NoSuchElementException - if no line was found IllegalStateException - if this scanner is closed

上面这段话是说 nextLine()这个扫描器是从每行开始进行扫描,直到识别到行尾的分隔符,输出开始到分隔符间的内容,不包括分隔符。然后把扫描器的位置置于下一行的开始。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值