nextLine()紧跟在nextXXX()后面读取不到数据的问题,以及两者的小结

用Java在在线oj平台上做题时,要求的标准输入一般是“Scanner cin=new Scanner(System.in);”。

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

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

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

代码如下:

  1 import java.math.BigDecimal;
  2 import java.math.BigInteger;
  3 import java.util.Scanner;
  4
  5 /**
  6  *  测试:1.所有的nextXXX()方法(包括next()),后面直接跟nextLine()读取数据;
  7  *  2.先加一句nextLine(),再用nextLine()读取数据,两者的区别。
  8  *  将每个代码块中间的注释"//cin.nextLine()",去掉"//",即可实现第2种方法。
  9  *  @author Hubert
 10  *
 11  */
 12 public class ScannerTest {
 13
 14     public static void main(String[] args) {
 15         // TODO Auto-generated method stub
 16     Scanner cin=new Scanner(System.in);
 17
 18     //测试cin.next()
 19     System.out.println("测试 cin.next()后面紧跟着nextLine()读取数据:");
 20     System.out.println("请输入一个字符串:");
 21     String next=cin.next();
 22     //cin.nextLine();
 23     System.out.println("请输入一个字符串:");
 24     String nextLine1=cin.nextLine();
 25     System.out.println("next()方法读取的值为:"+next);
 26     System.out.println("nextLine()方法读取的值为:"+nextLine1+"\n");
 27
 28     //测试cin.nextInt()
 29     System.out.println("测试cin.nextInt()后面紧跟着nextLine()读取数据:");
 30     System.out.println("请输入一个整数:");
 31     int nextInt=cin.nextInt();
 32     //cin.nextLine();
 33     System.out.println("请输入一个字符串:");
 34     String nextLine2=cin.nextLine();
 35     System.out.println("nextInt()方法读取的值为:"+nextInt);
 36     System.out.println("nextLine()方法读取的值为:"+nextLine2+"\n");
 37
 38     //测试cin.nextDouble()
 39     System.out.println("测试cin.nextDouble()后面紧跟着nextLine()读取数据:");
 40     System.out.println("请输入一个小数:");
 41     double nextDouble=cin.nextDouble();
 42     //cin.nextLine();
 43     System.out.println("请输入一个字符串:");
 44     String nextLine3=cin.nextLine();
 45     System.out.println("nextDouble()方法读取的值为:"+nextDouble);
 46     System.out.println("nextLine()方法读取的值为:"+nextLine3+"\n");
 47
 48     //测试cin.nextFloat()
 49     System.out.println("测试cin.nextFloat()后面紧跟着nextLine()读取数据:");
 50     System.out.println("请输入一个小数:");
 51     float nextFloat=cin.nextFloat();
 52     //cin.nextLine();
 53     System.out.println("请输入一个字符串:");
 54     String nextLine4=cin.nextLine();
 55     System.out.println("nextFloat()方法读取的值为:"+nextFloat);
 56     System.out.println("nextLine()方法读取的值为:"+nextLine4+"\n");
 57
 58     //测试cin.nextBoolean()
 59     System.out.println("测试cin.nextBoolean()后面紧跟着nextLine()读取数据:");
 60     System.out.println("请输入一个布尔值(true或者false):");
 61     boolean nextBoolean=cin.nextBoolean();
 62     //cin.nextLine();
 63     System.out.println("请输入一个字符串:");
 64     String nextLine5=cin.nextLine();
 65     System.out.println("nextBoolean()方法读取的值为:"+nextBoolean);
 66     System.out.println("nextLine()方法读取的值为:"+nextLine5+"\n");
 67
 68     //测试cin.nextLong()
 69     System.out.println("测试cin.nextLong()后面紧跟着nextLine()读取数据:");
 70     System.out.println("请输入一个整数:");
 71     long nextLong=cin.nextLong();
 72     //cin.nextLine();
 73     System.out.println("请输入一个字符串:");
 74     String nextLine6=cin.nextLine();
 75     System.out.println("nextLong()方法读取的值为:"+nextLong);
 76     System.out.println("nextLine()方法读取的值为:"+nextLine6+"\n");
 77
 78     //测试cin.nextByte()
 79     System.out.println("测试cin.nextByte()后面紧跟着nextLine()读取数据:");
 80     System.out.println("请输入一个整数(-128~127):");
 81     byte nextByte=cin.nextByte();
 82     //cin.nextLine();
 83     System.out.println("请输入一个字符串:");
 84     String nextLine7=cin.nextLine();
 85     System.out.println("nextByte()方法读取的值为:"+nextByte);
 86     System.out.println("nextLine()方法读取的值为:"+nextLine7+"\n");
 87
 88     //测试cin.nextShort()
 89     System.out.println("测试cin.nextShort()后面紧跟着nextLine()读取数据:");
 90     System.out.println("请输入一个整数:");
 91     short nextShort=cin.nextShort();
 92     //cin.nextLine();
 93     System.out.println("请输入一个字符串:");
 94     String nextLine8=cin.nextLine();
 95     System.out.println("nextShort()方法读取的值为:"+nextShort);
 96     System.out.println("nextLine()方法读取的值为:"+nextLine8+"\n");
 97
 98     //测试cin.nextBigInteger()
 99     System.out.println("测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:");
100     System.out.println("请输入一个整数:");
101     BigInteger nextBigInteger=cin.nextBigInteger();//扫描下一个输入作为BigInteger(可以实现任意大的大数)
102     //cin.nextLine();
103     System.out.println("请输入一个字符串:");
104     String nextLine9=cin.nextLine();
105     System.out.println("nextBigInteger()方法读取的值为::"+nextBigInteger);
106     System.out.println("nextLine()方法读取的值为:"+nextLine9+"\n");
107
108     //测试cin.nextBigDecimal()
109     System.out.println("测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:");
110     System.out.println("请输入一个小数:");
111     BigDecimal nextBigDecimal=cin.nextBigDecimal();//扫描下一个输入作为BigDecimal(可以实现任意精度)
112     //cin.nextLine();
113     System.out.println("请输入一个字符串:");
114     String nextLine10=cin.nextLine();
115     System.out.println("nextBigDecimal()方法读取的值为:"+nextBigDecimal);
116     System.out.println("nextLine()方法读取的值为:"+nextLine10+"\n");
117
118     cin.close();
119     }
120 }

ScannerTest

根据提示,输入"test,2,3.0,4.0,true,5,6,7,8,9,10.0",输出结果如下:

 1 测试 cin.next()后面紧跟着nextLine()读取数据:
 2 请输入一个字符串:
 3 test
 4 请输入一个字符串:
 5 next()方法读取的值为:test
 6 nextLine()方法读取的值为:
 7
 8 测试cin.nextInt()后面紧跟着nextLine()读取数据:
 9 请输入一个整数:
10 2
11 请输入一个字符串:
12 nextInt()方法读取的值为:2
13 nextLine()方法读取的值为:
14
15 测试cin.nextDouble()后面紧跟着nextLine()读取数据:
16 请输入一个小数:
17 3.0
18 请输入一个字符串:
19 nextDouble()方法读取的值为:3.0
20 nextLine()方法读取的值为:
21
22 测试cin.nextFloat()后面紧跟着nextLine()读取数据:
23 请输入一个小数:
24 4.0
25 请输入一个字符串:
26 nextFloat()方法读取的值为:4.0
27 nextLine()方法读取的值为:
28
29 测试cin.nextBoolean()后面紧跟着nextLine()读取数据:
30 请输入一个布尔值(true或者false):
31 true
32 请输入一个字符串:
33 nextBoolean()方法读取的值为:true
34 nextLine()方法读取的值为:
35
36 测试cin.nextLong()后面紧跟着nextLine()读取数据:
37 请输入一个整数:
38 6
39 请输入一个字符串:
40 nextLong()方法读取的值为:6
41 nextLine()方法读取的值为:
42
43 测试cin.nextByte()后面紧跟着nextLine()读取数据:
44 请输入一个整数(-128~127):
45 7
46 请输入一个字符串:
47 nextByte()方法读取的值为:7
48 nextLine()方法读取的值为:
49
50 测试cin.nextShort()后面紧跟着nextLine()读取数据:
51 请输入一个整数:
52 8
53 请输入一个字符串:
54 nextShort()方法读取的值为:8
55 nextLine()方法读取的值为:
56
57 测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:
58 请输入一个整数:
59 9
60 请输入一个字符串:
61 nextBigInteger()方法读取的值为::9
62 nextLine()方法读取的值为:
63
64 测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:
65 请输入一个小数:
66 10.0
67 请输入一个字符串:
68 nextBigDecimal()方法读取的值为:10.0
69 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"。输出结果为:

 1 测试 cin.next()后面紧跟着nextLine()读取数据:
 2 请输入一个字符串:
 3 test
 4 请输入一个字符串:
 5 line1
 6 next()方法读取的值为:test
 7 nextLine()方法读取的值为:line1
 8
 9 测试cin.nextInt()后面紧跟着nextLine()读取数据:
10 请输入一个整数:
11 2
12 请输入一个字符串:
13 line2
14 nextInt()方法读取的值为:2
15 nextLine()方法读取的值为:line2
16
17 测试cin.nextDouble()后面紧跟着nextLine()读取数据:
18 请输入一个小数:
19 3.0
20 请输入一个字符串:
21 line3
22 nextDouble()方法读取的值为:3.0
23 nextLine()方法读取的值为:line3
24
25 测试cin.nextFloat()后面紧跟着nextLine()读取数据:
26 请输入一个小数:
27 4.0
28 请输入一个字符串:
29 line4
30 nextFloat()方法读取的值为:4.0
31 nextLine()方法读取的值为:line4
32
33 测试cin.nextBoolean()后面紧跟着nextLine()读取数据:
34 请输入一个布尔值(true或者false):
35 true
36 请输入一个字符串:
37 line5
38 nextBoolean()方法读取的值为:true
39 nextLine()方法读取的值为:line5
40
41 测试cin.nextLong()后面紧跟着nextLine()读取数据:
42 请输入一个整数:
43 6
44 请输入一个字符串:
45 line6
46 nextLong()方法读取的值为:6
47 nextLine()方法读取的值为:line6
48
49 测试cin.nextByte()后面紧跟着nextLine()读取数据:
50 请输入一个整数(-128~127):
51 7
52 请输入一个字符串:
53 line7
54 nextByte()方法读取的值为:7
55 nextLine()方法读取的值为:line7
56
57 测试cin.nextShort()后面紧跟着nextLine()读取数据:
58 请输入一个整数:
59 8
60 请输入一个字符串:
61 line8
62 nextShort()方法读取的值为:8
63 nextLine()方法读取的值为:line8
64
65 测试cin.nextBigInteger()后面紧跟着nextLine()读取数据:
66 请输入一个整数:
67 9
68 请输入一个字符串:
69 line9
70 nextBigInteger()方法读取的值为::9
71 nextLine()方法读取的值为:line9
72
73 测试cin.nextBigDecimal()后面紧跟着nextLine()读取数据:
74 请输入一个小数:
75 10.0
76 请输入一个字符串:
77 line10
78 nextBigDecimal()方法读取的值为:10.0
79 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()方法也是这个原理。

时间: 2024-10-13 09:11:53

nextLine()紧跟在nextXXX()后面读取不到数据的问题,以及两者的小结的相关文章

JAVA TcpServer端使用Scanner读取不到数据的解决办法

在使用JAVA进行Socket通信时,在Server端使用Scanner的nextLine()方法读取数据时,一直读取不到数据是因为Scanner是一个扫描器,它扫描数据都是去内存中一块缓冲区中进行扫描并读入数据的,而我们在控制台中输入的数据也都是被先存入缓冲区中等待扫描器的扫描读取.这个扫描器在扫描过程中判断停止的依据就是“空白符”,空格.回车都算做是空白符.nextInt()方法在扫描到空白符的时候会将前面的数据读取走,但会丢下空白符“\r”在缓冲区中,但是,nextLine()方法在扫描的

java.sql.SQLException: 无法从套接字读取更多的数据(mybatis 插入时)

今天  做mybatis 的批量插入的时候  出现 java.sql.SQLException: 无法从套接字读取更多的数据   的错误 解决方法: 由于批量插入的数据过大,需要分批次的插入. List<IdentificationData> insertList = new ArrayList<IdentificationData>(); for (IdentificationData domain : list) { insertList.add(domain); //批量插入

java通过POI技术操作Excel(2)----模板读取,录入数据

先来回顾下通常把java对Excel的操作分为以下功能:1.生成模板,导出模板:2.填充模板,录入数据:3:读取数据库数据,导出数据:在上一篇博文中,我简单记录了模板生成和导出,在这篇博文中,主要来记录--Excel文件导入,数据录入(仍然是以jsp+servlet为例) 既然要解决这个问题,那首先来分析下我们需要面对的有哪些需求需要实现: 1.Excel文件导入(这是最基础的,巧妇难为无米之炊,导入环节也是查了好久才完成的); 2.Excel文件中数据的格式判定,你要读取文件,如果文件中其实没

c#用NPOI将excel文件内容读取到datatable数据表中

将excel文件内容读取到datatable数据表中,支持97-2003和2007两种版本的excel 1.第一种是根据excel文件路径读取excel并返回datatable 1 /// <summary> 2 /// 将excel文件内容读取到DataTable数据表中 3 /// </summary> 4 /// <param name="fileName">文件完整路径名</param> 5 /// <param name=

读取文档数据的各列的每行中

读取文档数据的各列的每行中 1.该文件的内容被读 [[email protected] leekwen]# cat userpwd 1412230101 ty001 1412230102 ty002 1512430102 ty003 1511230102 ty004 1411230102 ty002 1411240102 yt005 1412290102 yt012 1510230102 yt022 1512231212 yt032 2.脚本命令 [[email protected] leekw

从数据库里随机读取几条数据

从数据库里随机读取几条数据 Access: select top n * from table order by rnd(id)‘id为数据库的自动编号字段 Sql Server: select top n * from table order by newid() MySQL: SELECT * FROM table order by rand() limit  20; Oracle: select * from table order by dbms_random.value()

ACCESS(VBA)上的一个小项目 —— 2、读取ACCESS表数据到TreeView和ListView

有人问我能不能做一个程序的时候,我第一反应都说“能”. --这次在ACCESS中,借助TreeView和ListView做了一个数据联动的模型. 简析过程: 1)从网上找了一份TreeView学习教程<三小时学会树控件>,了解了TreeView的建立以及节点的使用方法: 2)把数据表中的某列按一定规则生成的数据再按一种规则解析成TreeView中的树结构(VPPS): 3)通过遍历TreeView中节点的折叠状态,通过上述一定规则生成的数据(唯一性)把数据表中的内容读取到ListView中:

Unity基础 用C#脚本读取JSON文件数据

读取JSON文件数据网上有很多方法吗,这里采用SimpleJSON,关于SimpleJSON的介绍参考以下链接:http://wiki.unity3d.com/index.php/SimpleJSON,使用之前要先导入SimpleJSON的相关文件. JSON文件名:achieve.json,文件内容: { "30002":{"achieve_id":30002,"achieve_name":"连胜","achiev

网络编程 --- URLConnection --- 读取服务器的数据 --- java

使用URLConnection类获取服务器的数据 抽象类URLConnection表示一个指向指定URL资源的活动连接,它是java协议处理器机制的一部分. URL对象的openConnection()方法就是调用了URLStreamHandler的openConnection()方法. 如有疑问请参考:JAVA网络编程[第三版], 如下图: 怎样获取服务器输出的数据呢?代码如下: import java.io.IOException; import java.io.InputStream; i