java中nextLine读取不到的问题

要求的标准输入一般是“Scanner cin=new Scanner(System.in);”。

其实还有更有效率的方法:Scanner cin=new Scanner(new BufferedInputStream(System.in))。笔者更常用这种方法,效率更高。但是由于本文主题不在于此,因此不再赘述。

回到正题,之前就发现nextXXX()(包括next()方法)后面紧跟nextLine()的话,后者不会读取到数据,输出的话为空字符串。这两天做了几个题,又涉及到这个问题了。既然开博了,就把这个问题分析、总结,记录下来,以后忘了的话翻翻博客就记起来了。

写了一段代码,测试所有的cin.nextXXX()方法。

代码如下:
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;

/**
 *  测试:1.所有的nextXXX()方法(包括next()),后面直接跟nextLine()读取数据;
 *  2.先加一句nextLine(),再用nextLine()读取数据,两者的区别。
 *  将每个代码块中间的注释"//cin.nextLine()",去掉"//",即可实现第2种方法。
 *  @author Hubert
 *
 */
public class ScannerTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
    Scanner cin=new Scanner(System.in);
    
    //测试cin.next()
    System.out.println("测试 cin.next()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个字符串:");
    String next=cin.next();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine1=cin.nextLine();
    System.out.println("next()方法读取的值为:"+next);
    System.out.println("nextLine()方法读取的值为:"+nextLine1+"\n");
    
    //测试cin.nextInt()
    System.out.println("测试cin.nextInt()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个整数:");
    int nextInt=cin.nextInt();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine2=cin.nextLine();
    System.out.println("nextInt()方法读取的值为:"+nextInt);
    System.out.println("nextLine()方法读取的值为:"+nextLine2+"\n");
    
    //测试cin.nextDouble()
    System.out.println("测试cin.nextDouble()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个小数:");
    double nextDouble=cin.nextDouble();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine3=cin.nextLine();
    System.out.println("nextDouble()方法读取的值为:"+nextDouble);
    System.out.println("nextLine()方法读取的值为:"+nextLine3+"\n");
    
    //测试cin.nextFloat()
    System.out.println("测试cin.nextFloat()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个小数:");
    float nextFloat=cin.nextFloat();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine4=cin.nextLine();
    System.out.println("nextFloat()方法读取的值为:"+nextFloat);
    System.out.println("nextLine()方法读取的值为:"+nextLine4+"\n");
    
    //测试cin.nextBoolean()
    System.out.println("测试cin.nextBoolean()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个布尔值(true或者false):");
    boolean nextBoolean=cin.nextBoolean();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine5=cin.nextLine();
    System.out.println("nextBoolean()方法读取的值为:"+nextBoolean);
    System.out.println("nextLine()方法读取的值为:"+nextLine5+"\n");
    
    //测试cin.nextLong()
    System.out.println("测试cin.nextLong()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个整数:");
    long nextLong=cin.nextLong();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine6=cin.nextLine();
    System.out.println("nextLong()方法读取的值为:"+nextLong);
    System.out.println("nextLine()方法读取的值为:"+nextLine6+"\n");
    
    //测试cin.nextByte()
    System.out.println("测试cin.nextByte()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个整数(-128~127):");
    byte nextByte=cin.nextByte();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine7=cin.nextLine();
    System.out.println("nextByte()方法读取的值为:"+nextByte);
    System.out.println("nextLine()方法读取的值为:"+nextLine7+"\n");
    
    //测试cin.nextShort()
    System.out.println("测试cin.nextShort()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个整数:");
    short nextShort=cin.nextShort();
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine8=cin.nextLine();
    System.out.println("nextShort()方法读取的值为:"+nextShort);
    System.out.println("nextLine()方法读取的值为:"+nextLine8+"\n");
    
    //测试cin.nextBigInteger()
    System.out.println("测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个整数:");
    BigInteger nextBigInteger=cin.nextBigInteger();//扫描下一个输入作为BigInteger(可以实现任意大的大数)
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine9=cin.nextLine();
    System.out.println("nextBigInteger()方法读取的值为::"+nextBigInteger);
    System.out.println("nextLine()方法读取的值为:"+nextLine9+"\n");
    
    //测试cin.nextBigDecimal()
    System.out.println("测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:");
    System.out.println("请输入一个小数:");
    BigDecimal nextBigDecimal=cin.nextBigDecimal();//扫描下一个输入作为BigDecimal(可以实现任意精度)
    //cin.nextLine();
    System.out.println("请输入一个字符串:");
    String nextLine10=cin.nextLine();
    System.out.println("nextBigDecimal()方法读取的值为:"+nextBigDecimal);
    System.out.println("nextLine()方法读取的值为:"+nextLine10+"\n");
    
    cin.close();
    } 
}

ScannerTest
测试 cin.next()后面紧跟着nextLine()读取数据:
请输入一个字符串:
test
请输入一个字符串:
next()方法读取的值为:test
nextLine()方法读取的值为:

测试cin.nextInt()后面紧跟着nextLine()读取数据:
请输入一个整数:
2
请输入一个字符串:
nextInt()方法读取的值为:2
nextLine()方法读取的值为:

测试cin.nextDouble()后面紧跟着nextLine()读取数据:
请输入一个小数:
3.0
请输入一个字符串:
nextDouble()方法读取的值为:3.0
nextLine()方法读取的值为:

测试cin.nextFloat()后面紧跟着nextLine()读取数据:
请输入一个小数:
4.0
请输入一个字符串:
nextFloat()方法读取的值为:4.0
nextLine()方法读取的值为:

测试cin.nextBoolean()后面紧跟着nextLine()读取数据:
请输入一个布尔值(true或者false):
true
请输入一个字符串:
nextBoolean()方法读取的值为:true
nextLine()方法读取的值为:

测试cin.nextLong()后面紧跟着nextLine()读取数据:
请输入一个整数:
6
请输入一个字符串:
nextLong()方法读取的值为:6
nextLine()方法读取的值为:

测试cin.nextByte()后面紧跟着nextLine()读取数据:
请输入一个整数(-128~127):
7
请输入一个字符串:
nextByte()方法读取的值为:7
nextLine()方法读取的值为:

测试cin.nextShort()后面紧跟着nextLine()读取数据:
请输入一个整数:
8
请输入一个字符串:
nextShort()方法读取的值为:8
nextLine()方法读取的值为:

测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:
请输入一个整数:
9
请输入一个字符串:
nextBigInteger()方法读取的值为::9
nextLine()方法读取的值为:

测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:
请输入一个小数:
10.0
请输入一个字符串:
nextBigDecimal()方法读取的值为:10.0
nextLine()方法读取的值为:

输出结果1

发现所有的cin.nextXXX()方法,后面紧跟cin.nextLine()读取数据的话,cin.nextLine()是读取不到数据的,在结果中可以看到每个cin.nextLine()读取到的都是空字符串。

查看了一下Javadoc中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.”。nextLine()官方说明是跳过当前行,并且返回被跳过的输入。这个方法能够返回当前行剩余的内容,排除行尾的行分隔符在外。最终将光标设定在下一行的开始。该方法会从光标处开始扫描,直到遇到行分隔符(\r\n),然后返回扫描的内容,并将光标设置为下一行的开始。上述的测试中,因为在输入内容后,需要敲击回车才能使程序继续执行。此时相当于光标和行分隔符(回车)之间内容为"",因此自然cin.nextLine()读取到的是""了。

解决方法就是在cin.nextXXX()方法后,在加一个cin.nextLine(),作用是跳过该行的剩余内容(即""),并将光标设置为下一行的开始。

在上述代码中,将每个代码块中的"//cin.nextLine()"中的注释符号去掉,再次进行测试。根据提示,输入"test,line1,2,line2,3.0,line3,4.0,line4,true,line5,6,line6,7,line7,8,line8,9,line9,10.0,line10"。输出结果为:
测试 cin.next()后面紧跟着nextLine()读取数据:
请输入一个字符串:
test
请输入一个字符串:
line1
next()方法读取的值为:test
nextLine()方法读取的值为:line1

测试cin.nextInt()后面紧跟着nextLine()读取数据:
请输入一个整数:
2
请输入一个字符串:
line2
nextInt()方法读取的值为:2
nextLine()方法读取的值为:line2

测试cin.nextDouble()后面紧跟着nextLine()读取数据:
请输入一个小数:
3.0
请输入一个字符串:
line3
nextDouble()方法读取的值为:3.0
nextLine()方法读取的值为:line3

测试cin.nextFloat()后面紧跟着nextLine()读取数据:
请输入一个小数:
4.0
请输入一个字符串:
line4
nextFloat()方法读取的值为:4.0
nextLine()方法读取的值为:line4

测试cin.nextBoolean()后面紧跟着nextLine()读取数据:
请输入一个布尔值(true或者false):
true
请输入一个字符串:
line5
nextBoolean()方法读取的值为:true
nextLine()方法读取的值为:line5

测试cin.nextLong()后面紧跟着nextLine()读取数据:
请输入一个整数:
6
请输入一个字符串:
line6
nextLong()方法读取的值为:6
nextLine()方法读取的值为:line6

测试cin.nextByte()后面紧跟着nextLine()读取数据:
请输入一个整数(-128~127):
7
请输入一个字符串:
line7
nextByte()方法读取的值为:7
nextLine()方法读取的值为:line7

测试cin.nextShort()后面紧跟着nextLine()读取数据:
请输入一个整数:
8
请输入一个字符串:
line8
nextShort()方法读取的值为:8
nextLine()方法读取的值为:line8

测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:
请输入一个整数:
9
请输入一个字符串:
line9
nextBigInteger()方法读取的值为::9
nextLine()方法读取的值为:line9

测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:
请输入一个小数:
10.0
请输入一个字符串:
line10
nextBigDecimal()方法读取的值为:10.0
nextLine()方法读取的值为:line10

输出结果2

这次cin.nextLine()能够成功地读取数据了。
看了一下next()方法的说明。“Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.”。意思是找到并返回扫描到的完整的标记,而一个完整的标记处于分隔符之间(处于行首的标记,可以看做是在换行"\r\n"这个分隔符之后)。就是说读取并返回两个分隔符之间的标记(token)。比如说输入“ input “,标记"input"被两个分隔符(空格)夹在中间,那么这个方法会读取并返回"input”。其他的nextXXX()方法也是这个原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值