StreamTokenizer读不到TT_EOL
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相关推荐
- StreamTokenizer输入中的用法
StreamTokenizer用来分隔字符串. 可以获取输入流并将其分析为Token(标记).StreamTokenizer的nextToken方法将读取下一个标记. 功能 1. 将输入流分解成一组 ...
- Java StreamTokenizer nextToken()方法与示例
StreamTokenizer类nextToken()方法 (StreamTokenizer Class nextToken() method) nextToken() method is avail ...
- Java StreamTokenizer quoteChar()方法与示例
StreamTokenizer类quoteChar()方法 (StreamTokenizer Class quoteChar() method) quoteChar() method is avail ...
- Java StreamTokenizer whitespaceChars()方法及示例
StreamTokenizer类whitespaceChars()方法 (StreamTokenizer Class whitespaceChars() method) whitespaceChars ...
- Java的快读快输出
众所周知,Java Scanner类的读入的真的真的慢 在我们使用Scanner类进行读入数据时,数据一旦过万,他就会显得非常慢 而用StreamTokenizer类差不多好像是要比Scanner快个 ...
- acm竞赛技巧——c/c++ /java 快读快写(整数,字符串)
文章目录 整数 快读 快写 字符串 读入 读出 java快读快输 注意: 本文参考博客 整数 这里用int做示范,long long,__int128 改下变量类型即可 快读 inline int r ...
- java算法竞赛必备之快读快写(超详细解读)
java算法竞赛必备之快读快写(超详细解读) java写算法的缺点:速度慢.读写复杂.莫名WA(错误答案).TL(超时).CL(超内存)- (那我们还学个啥啊,都转c++写算法不香嘛.)别急别急,有缺 ...
- Java StreamTokenizer pushBack()方法与示例
StreamTokenizer类pushBack()方法 (StreamTokenizer Class pushBack() method) pushBack() method is availabl ...
- BERT大火却不懂Transformer?读这一篇就够了 重点 命名实体识别
bert_config.josn 模型中参数的配置 { "attention_probs_dropout_prob": 0.1, #乘法attention时,softmax后dro ...
最新文章
- Windows10上编译MXNet源码操作步骤(Python)
- vue ts prop
- Ruby on Rails路径穿越与任意文件读取漏洞分析(CVE-2019-5418)
- 第十五章 五虎上将中谁最冷血
- 为何互联网大厂热衷于春节撒红包?谁才是最大赢家?
- Every column needs a corresponding expression. No expression found for xxxx
- leetcode193. 有效电话号码 正则了解一下
- 看懂 IPv6+,这篇就够了
- 【C语言重点难点精讲】C语言指针
- 天公不作美 SpaceX再次推迟星链卫星发射
- relative和absolute使用
- 不同人眼中的“顶级程序员”,这差距也太大了吧!
- pytorch.max()的详细解释
- 如何将MKV的字幕提取出来
- roboware studio教程_2.2.RoboWare Studio安装及使用
- 研究生英语读写译教程下课文译文及课后答案2
- spring事务管理器的源码和理解
- java打印字符串显示_JAVA调用系统打印机打印字符串
- 递归算法_字符串反转_20230412
- [B2R]Raven: 2靶机