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
- Windows系统:输入完内容后按
这样修改后,程序就能正确读取控制台输入的整数并存入ArrayList,不会陷入无限循环。
内容的提问来源于stack exchange,提问作者Ogurcius
相关产品推荐
相关产品推荐

