遇到下划线时,java.io.StreamTokenizer会生成空令牌

时间:2015-02-26 17:53:14

标签: java stream null tokenize java-io

我有一个用于解析令牌的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);
        }
    }
}

1 个答案:

答案 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,不在边界内。