You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java初学者使用StreamTokenizer从控制台读取输入时遭遇无限循环问题

StreamTokenizer控制台输入无限循环问题

我是一名Java初学者,学习StreamTokenizer时遇到了一个问题,网上没找到解决方案。

几乎所有教学资料都给出这样的示例代码,运行完全正常:

import java.io.*;

public class pr_23 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer st = new StreamTokenizer(br);
        
        while (st.nextToken() != st.TT_EOF)
            if (st.ttype == st.TT_NUMBER)
                System.out.print(st.nval + " "); // 不会无限循环
        
        br.close();
    }
}

但当我移除System.out.print(),换成将数字存入ArrayList的操作时,程序就无法识别流结束,陷入无限读取状态。用FileInputStream替代InputStreamReader时代码能正常运行,但我需要从控制台获取输入,且StreamTokenizer直接使用FileInputStream已被废弃。存在问题的代码如下:

import java.io.*;
import java.util.ArrayList;

public class pr_23 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer st = new StreamTokenizer(br);
    
        ArrayList<Integer> a = new ArrayList<>();
        
        while (st.nextToken() != st.TT_EOF) {
            a.add((int)st.nval);   // 无限循环
        }
        System.out.print(a);
        
        br.close();
    }
}

备注:输入仅为整数,已简化问题。


问题原因与解决方案

  • 缺少token类型判断:示例代码中会先判断当前token是否为TT_NUMBER再处理,而有问题的代码直接存取st.nval。如果输入中存在非数字token(比如意外的空白或其他字符),会导致st.nval读取异常,甚至让nextToken()陷入异常循环。必须在存入列表前判断token类型:
    while (st.nextToken() != st.TT_EOF) {
        if (st.ttype == st.TT_NUMBER) { // 先判断是否为数字
            a.add((int)st.nval);
        }
    }
    
  • 控制台输入需手动触发EOF:从控制台读取输入时,StreamTokenizer不会自动识别输入结束,必须手动发送EOF信号:
    • Windows系统:输入完内容后按 Ctrl + Z,再按回车
    • Linux/macOS系统:输入完内容后按 Ctrl + D

这样修改后,程序就能正确读取控制台输入的整数并存入ArrayList,不会陷入无限循环。

内容的提问来源于stack exchange,提问作者Ogurcius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:50:18