pre

在刷题的时候发现有些大神用StreamTokenizer来减少数据读入时间,经过尝试,在读入数据多的情况下,这部分节省出来的时间是比较明显的。但是在尝试反转句子[^题目]的时候,我需要处理换行符的问题,我发现EOL标识一直读不到,最终在stackoverflow上找到了答案,我在这里把经验分享给大家。

问题简述

代码如下:

public static void main(String[] args){StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));Stack<String> sentence = new Stack<>();StringBuffer sb = new StringBuffer();try {while(in.nextToken() != StreamTokenizer.TT_EOF){if(in.ttype == StreamTokenizer.TT_EOL){while(sentence.size()>0){sb.append(sentence.pop());if(sentence.size() > 0){sb.append(' ');}else{sb.append('\n');}}}else{sentence.push(in.sval);}}System.out.println(sb.toString());} catch (IOException e) {e.printStackTrace();}}

输入数据如下

hello xiao mi
hello xiao mi

在debug过程中,

in.ttype == StreamTokenizer.TT_EOL

这个条件恒为false

所以初步问题定位为 StreamTokenizer的nextToken方法会跳过EOL标签

解决方案

参考大神回答[^大神回答] ,在初始化StreamTokenizer的时候需要执行以下一下语句

in.eolIsSignificant(true);

再默认情况下nextToken会忽略EOL标记,上面这行语句可以避免nextToken跳过。

回溯源码(执果索因)

首先检查nextToken方法,检查是否会返回EOL

//在nextToken找到如下代码
if (c == '\r') {LINENO++;if (eolIsSignificantP) {peekc = SKIP_LF;return ttype = TT_EOL;}c = read();if (c == '\n')c = read();
} else {if (c == '\n') {LINENO++;if (eolIsSignificantP) {return ttype = TT_EOL;}}c = read();
}

根据上述代码,我们可以确认nextToken是会返回EOL的,但是eolIsSignificantP决定了是否返回,那么我们下一步检查eolIsSignificantP相关的代码。

//初始化
private boolean eolIsSignificantP = false;
/*** Determines whether or not ends of line are treated as tokens.* If the flag argument is true, this tokenizer treats end of lines* as tokens; the {@code nextToken} method returns* {@code TT_EOL} and also sets the {@code ttype} field to* this value when an end of line is read.* <p>* A line is a sequence of characters ending with either a* carriage-return character ({@code '\u005Cr'}) or a newline* character ({@code '\u005Cn'}). In addition, a carriage-return* character followed immediately by a newline character is treated* as a single end-of-line token.* <p>* If the {@code flag} is false, end-of-line characters are* treated as white space and serve only to separate tokens.** @param   flag   {@code true} indicates that end-of-line characters*                 are separate tokens; {@code false} indicates that*                 end-of-line characters are white space.* @see     java.io.StreamTokenizer#nextToken()* @see     java.io.StreamTokenizer#ttype* @see     java.io.StreamTokenizer#TT_EOL*/public void eolIsSignificant(boolean flag) {eolIsSignificantP = flag;}

找到这两段代码,我们就可以知道解决方案了

总结

源码是最好的说明文件

reference

JDK 1.8 源码
[^题目] : http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3330&konwledgeId=155
[^大神回答] : https://stackoverflow.com/questions/31152497/end-of-line-not-reading-stream-tokenize-java

StreamTokenizer读不到TT_EOL相关推荐

  1. StreamTokenizer输入中的用法

    StreamTokenizer用来分隔字符串. 可以获取输入流并将其分析为Token(标记).StreamTokenizer的nextToken方法将读取下一个标记. 功能  1. 将输入流分解成一组 ...

  2. Java StreamTokenizer nextToken()方法与示例

    StreamTokenizer类nextToken()方法 (StreamTokenizer Class nextToken() method) nextToken() method is avail ...

  3. Java StreamTokenizer quoteChar()方法与示例

    StreamTokenizer类quoteChar()方法 (StreamTokenizer Class quoteChar() method) quoteChar() method is avail ...

  4. Java StreamTokenizer whitespaceChars()方法及示例

    StreamTokenizer类whitespaceChars()方法 (StreamTokenizer Class whitespaceChars() method) whitespaceChars ...

  5. Java的快读快输出

    众所周知,Java Scanner类的读入的真的真的慢 在我们使用Scanner类进行读入数据时,数据一旦过万,他就会显得非常慢 而用StreamTokenizer类差不多好像是要比Scanner快个 ...

  6. acm竞赛技巧——c/c++ /java 快读快写(整数,字符串)

    文章目录 整数 快读 快写 字符串 读入 读出 java快读快输 注意: 本文参考博客 整数 这里用int做示范,long long,__int128 改下变量类型即可 快读 inline int r ...

  7. java算法竞赛必备之快读快写(超详细解读)

    java算法竞赛必备之快读快写(超详细解读) java写算法的缺点:速度慢.读写复杂.莫名WA(错误答案).TL(超时).CL(超内存)- (那我们还学个啥啊,都转c++写算法不香嘛.)别急别急,有缺 ...

  8. Java StreamTokenizer pushBack()方法与示例

    StreamTokenizer类pushBack()方法 (StreamTokenizer Class pushBack() method) pushBack() method is availabl ...

  9. BERT大火却不懂Transformer?读这一篇就够了 重点 命名实体识别

    bert_config.josn 模型中参数的配置 { "attention_probs_dropout_prob": 0.1, #乘法attention时,softmax后dro ...

最新文章

  1. Windows10上编译MXNet源码操作步骤(Python)
  2. vue ts prop
  3. Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)
  4. 第十五章 五虎上将中谁最冷血
  5. 为何互联网大厂热衷于春节撒红包?谁才是最大赢家?
  6. Every column needs a corresponding expression. No expression found for xxxx
  7. leetcode193. 有效电话号码 正则了解一下
  8. 看懂 IPv6+,这篇就够了
  9. 【C语言重点难点精讲】C语言指针
  10. 天公不作美 SpaceX再次推迟星链卫星发射
  11. relative和absolute使用
  12. 不同人眼中的“顶级程序员”,这差距也太大了吧!
  13. pytorch.max()的详细解释
  14. 如何将MKV的字幕提取出来
  15. roboware studio教程_2.2.RoboWare Studio安装及使用
  16. 研究生英语读写译教程下课文译文及课后答案2
  17. spring事务管理器的源码和理解
  18. java打印字符串显示_JAVA调用系统打印机打印字符串
  19. 递归算法_字符串反转_20230412
  20. [B2R]Raven: 2靶机

热门文章

  1. AfterShip 十周年演讲:创业是一场赢得信任,创造价值的修行
  2. 分贝dB与倍数的转换关系
  3. 在老家最长的寒假之旅
  4. 什么技术,让ta拿下中国移动大奖?
  5. 计算机动画文件是什么,计算机动画技术基本原理与应用
  6. 汇川AM系列掉电数据保持及变量
  7. springboot:根据不同配置注入不同实现的bean
  8. 图的存储——邻接表法
  9. 基于SSH的失物招领系统
  10. Past Simple