我有一个用于解析令牌的StreamTokenizer。当我将以下内容传递给stdin:
a b_c d
解析的标记(在stdout上)是:
a
b
null
c
d
为什么会这样?如果下划线是单词字符,则应该有3个标记,第二个标记为“b_c”。如果下划线是分隔符,则应该有4个令牌。我认为空令牌没有意义。
Q1:为什么有空令牌?
Q2:为什么有人会设计StreamTokenizer以产生空标记?
Ideone脚本:http://ideone.com/e.js/RFbPpJ
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer st = new StreamTokenizer(br);
while (st.nextToken() != StreamTokenizer.TT_EOF) {
System.out.println(st.sval);
}
}
}
答案 0 :(得分:1)
来自doc:
如果当前令牌是单词标记,则此字段包含字符串 给出令牌的字符。当前令牌是 引用字符串标记,此字段包含字符串的主体。该 当ttype字段的值为TT_WORD时,当前令牌是一个单词。 当ttype的值时,当前标记是带引号的字符串标记 field是引用字符。
此字段的初始值为null。
这意味着没有达到任何条件且null
被输出。
换句话说,下划线的ttype既不被视为单词也不被视为带引号的字符串。
ttype
的文档指定
调用nextToken方法后,该字段包含类型 刚读过的令牌。对于单个字符标记,其值为 单个字符,转换为整数。对于带引号的字符串标记, 它的值是引号字符。否则,它的值是其中之一 以下:TT_WORD表示令牌是一个单词。 TT_NUMBER 表示令牌是一个数字。 TT_EOL表示结束 线已被阅读。如果是,该字段只能具有此值 已使用参数true调用eolIsSignificant方法。 TT_EOF 表示已到达输入流的末尾。
此字段的初始值为-4。
请注意,-4值等于TT_NOTHING。
要将下划线识别为单词,您可以使用tokenizer.wordChars('_', '_');
wordChars用于指定范围为低&lt; =的所有字符c c <=高是单词成分。单词标记由一个单词组成 成分后跟零个或多个单词成分或数字 成分
如果您希望下划线是普通的char而不是单词char,那么还有一个method。
请注意,给予&#39; _&#39;因为wordChars的定界符只允许下划线为单词字符,所以你可能想设置适合你需要的界限。
编辑:为了回答你的评论,简而言之,下划线被视为标识符的一部分,这就是为什么它没有映射到任何东西因此返回null。
如果您查看StreamTokenizer类的未记录的私有构造函数,您将更好地了解每个char的处理方式:
private StreamTokenizer() {
wordChars('a', 'z');
wordChars('A', 'Z');
wordChars(128 + 32, 255);
whitespaceChars(0, ' ');
commentChar('/');
quoteChar('"');
quoteChar('\'');
parseNumbers();
}
下划线是ASCII码95,不在边界内。