15、Scanner的next、nextLine方法 与 \r、\n 的一点思考和总结
来源:互联网 发布:淘宝联盟怎么设置链接 编辑:程序博客网 时间:2024/06/07 02:37
注意:所有讨论仅基于windows平台,据说linux和mac都不一样,之后装了linux再来对比试试。
首先上一段代码:
public class ScannerTest {public static void main(String[] args){System.out.println("abcd\r123");System.out.println("final");}}在IDE中(我用的eclipse),运行结果是
abcd123final
用cmd,java命令运行,结果却不一样,结果是:
123dfinal
关于\r和\n的来历,有一个小故事,是这么说的:
“在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打
完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员
想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,
告诉打字机把纸向下移一行。 ”
\r就是回车,\n就是换行。很明显,控制台和eclipse对于“\r”的理解是不同的。
实际上当按下回车键时,传递给系统的是"\r\n"。之前关于Scanner的读入,我一直有一些疑问,结合这一点,算是弄清楚了,看以下代码:
<span style="font-family:SimSun;">import java.util.*;public class ScannerTest {public static void main(String[] args){Scanner sc = new Scanner(System.in);//sc.useDelimiter("\n");String s1 = sc.next();String s2 = sc.next();System.out.println(s1 + "; length : " + s1.length());System.out.println(s2 + "; length : " + s2.length());sc.close();}}</span>输入“1”,按一下回车,再输入“2”,按回车,结果是:
121; length : 12; length : 1很科学,可是Scanner的next()方法有个问题,就是会以空格,制表符等等来分隔字符串,比如调用一个next(),阻塞等待输入,输入“abc def”,则只会返回“abc”,下一次用next()会立即返回“def”。《疯狂java讲义》这个书里说,可以用useDelimiter("\n")来设定只以换行符来分隔,显然李刚就忘了还有"\r"这个东西,把上面代码的注释去掉:
import java.util.*;public class ScannerTest {public static void main(String[] args){Scanner sc = new Scanner(System.in);sc.useDelimiter("\n");String s1 = sc.next();String s2 = sc.next();System.out.println(s1 + "; length : " + s1.length());System.out.println(s2 + "; length : " + s2.length());sc.close();}}还是依旧输入“1”,按一下回车,再输入“2”,按回车,在eclipse中结果是:
121; length : 22; length : 2原因很简单,只以"\n"做分隔,那么next()返回的其实是“1\r”和“2\r”,而eclipse对"\r"的处理是换行加回车,即等同于“\r\n”的,所以在输出分号之前换了行,而且字符串长度也变成了2。如果改成sc.useDelimiter("\r\n");自然就一切正常了。
同时也可以预想上面那段代码在命令行中的结果,返回的"1\r"输出1之后,光标回到行首,再输出“;length ……”就把“1”给覆盖了。
再说说next()和nextLine(),nextLine()的行为有点不一样,把上面的代码改一下:
import java.util.*;public class ScannerTest {public static void main(String[] args){Scanner sc = new Scanner(System.in);sc.useDelimiter("\n");String s1 = sc.next();String s2 = sc.nextLine();System.out.println(s1 + "; length : " + s1.length());System.out.println(s2 + "; length : " + s2.length());sc.close();}}还是输入“1”,回车,“2”,回车。
但是输入“1”,回车之后,程序直接就全部输出了,结果是
1//这是输入1; length : 2; length : 0看了一下Scanner的文档,对于next()是这样说的
public String next()
hasNext()
returned true
.而对于nextLine()是这样描述的:
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.
显然,对于nextLine()完全没有提delimiter pattern,所以说nextLine()是不受useDelimiter方法约束的,nextLine直接跳啊跳啊,去找换行符。当输入“1”,按下回车时,其实输入给Scanner的是“1\r\n”,next方法对比着分隔符“\n",把“1\r”返回给了s1。此时定位还在\n处,即定位还没有换行,再调用nextLine,直接就发现一个“\n”于是把跳过的部分(空的)赋给了s2。
import java.util.*;public class ScannerTest {public static void main(String[] args){Scanner sc = new Scanner(System.in);sc.useDelimiter("\r\n");String s1 = sc.next();String s2 = sc.nextLine();System.out.println(s1 + "; length : " + s1.length());System.out.println(s2 + "; length : " + s2.length());sc.close();}}eclipse和命令行中运行的结果都是:
11; length : 1; length : 0假设nextLine只以“\n”来区分行,则“\r”会被赋给s2,但是s2长度为0,什么都没有,之前已经证明\r是要占长度的。所以说nextLine也是以“\r\n”来区分一行的。作为windows下正统的换行,也是合理的,猜想nextLine是找不到\r\n时再找\n,不过感觉好像也没什么区别。
再说说,nextInt(),nextDouble()这一类的方法,看下面代码:
import java.util.*;public class ScannerTest {public static void main(String[] args){Scanner sc = new Scanner(System.in);sc.useDelimiter("\n");String s1 = sc.next();Integer s2 = sc.nextInt();System.out.println(s1 + "; length : " + s1.length());System.out.println(s2 );sc.close();}}这个代码,执行时会出现java.util.InputMismatchException异常。原因很简单,分隔符是"\n"假设给nextInt输入“1”,回车,那么输入的就是“1\r\n”,去掉分隔符就是“1\r”,无法转换成Integer。把分隔符设置成“\r\n”就没问题了。
总之,李刚这个书,教人把分隔符设置成“\n”显然是不科学的,最近一直在看这本书,有点怀疑这书的水平了。希望他在讲I/O那章的时候能把这个东西说清楚。
- 15、Scanner的next、nextLine方法 与 \r、\n 的一点思考和总结
- Scanner的next与nextLine方法
- Scanner 的next() 与nextline()
- scanner.next()与scanner.nextLine()的区别
- Java中Scanner的nextInt(),next(),nextLine()方法总结
- Java中Scanner的nextInt(),next(),nextLine()方法总结
- Java中Scanner的nextInt(),next(),nextLine()方法总结
- java Scanner中的 next() 方法和 nextLine() 方法的区别
- Scanner中next()方法和nextLine()方法的区别
- Scanner中nextLine()方法和next()方法的区别
- Scanner中nextLine()方法和next()方法的使用概括
- Scanner的next,nextint和nextLine的使用总结
- Scanner的next,nextint和nextLine的使用总结
- Scanner类 next与nextLine方法的使用问题
- Scanner中next()和nextLine()方法的区别
- 浅析Java中Scanner的next()和nextLine()方法
- Java中Scanner类的next()和nextLine()方法对比
- Scanner的next()和nextLine()的区别
- iOS开发教程之ASIHTTPRequest:使用download cache
- 远程桌面连接的时候 屏幕一闪就没了 然后不能连接上
- android studio 更新 Gradle错误解决方法
- 关于jackson的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
- LeetCode算法题之Count and Say
- 15、Scanner的next、nextLine方法 与 \r、\n 的一点思考和总结
- js判断浏览器改变大小时触发事件
- Mac OS下安装ProtocolBuffer与iOS的简单使用
- 仿coc聊天框的cocos2d实现
- Rails4.2 ActiveAdminw文件上传
- EditText--输入法
- 自己写个回调玩玩
- MatConvnet里那21层结构
- ObjectC----实例变量的可见度