Java技术问题:Scanner无法识别文件中的double类型值
问题分析与解决方案
你的问题核心在于Scanner的默认分隔符设置不对,以及循环判断逻辑的小问题,导致带空格的国家名被错误拆分,最终引发类型匹配异常。
为什么会报错?
- 分隔符问题:你提到文件是制表符分隔的,但默认情况下,Scanner会把**所有空白字符(空格、制表符、换行)**都当作分隔符。这就导致像
Saint Lucia、Bosnia & Herzegovina这类带空格的国家名,被拆成了多个独立的token。比如fiSc.next()只会读到Saint,接下来的Lucia会被fiSc.nextInt()尝试读取,自然会抛出类型转换异常,整个读取顺序完全混乱,最后就出现了“无法识别最后一个token为double”的错误。 - 循环判断问题:你用
hasNextLine()来控制循环,但每次构造Country时会读取3个token(名字、人口、增长率),当一行里有多个国家数据时(比如你给出的示例),hasNextLine()只会判断是否还有行,不会判断是否还有足够的token来创建下一个Country。
解决方案
方案1:设置Scanner的分隔符为制表符(推荐)
直接告诉Scanner用制表符来分割字段,这样不管国家名里有多少空格,都会被当作一个完整的token读取。
// 初始化Scanner时指定分隔符为制表符 Scanner fiSc = new Scanner(new File("你的文件名.txt")); fiSc.useDelimiter("\t"); // 关键:覆盖默认分隔符 LinkedList<Country> temp = new LinkedList<>(); // 用hasNext()判断是否还有下一个国家的名字(确保有足够的token) while (fiSc.hasNext()) { temp.add(new Country(fiSc)); } // 你的Country构造方法可以保持不变 public Country(Scanner fiSc) { name = fiSc.next(); // 现在会读取完整的带空格的国家名 pop = fiSc.nextInt(); rate = fiSc.nextDouble(); }
方案2:按行读取后分割字段(更稳妥)
如果你的文件是每行对应一个国家(或者你想更精准控制字段读取),可以先读取整行,再按制表符分割字段:
Scanner fiSc = new Scanner(new File("你的文件名.txt")); LinkedList<Country> temp = new LinkedList<>(); while (fiSc.hasNextLine()) { String line = fiSc.nextLine(); // 按制表符分割成字段数组 String[] fields = line.split("\t"); // 解析字段并创建Country对象 String name = fields[0]; int pop = Integer.parseInt(fields[1]); double rate = Double.parseDouble(fields[2]); temp.add(new Country(name, pop, rate)); } // 需要给Country添加一个带参数的构造方法 public Country(String name, int pop, double rate) { this.name = name; this.pop = pop; this.rate = rate; }
注意事项
- 一定要确认你的文件确实是用制表符分隔的,而不是空格。可以用文本编辑器(比如Notepad++)开启“显示所有字符”功能,查看分隔符是否为制表符(通常显示为
→)。 - 如果你的文件一行包含多个国家数据(像你给出的示例),方案1会更合适,因为它会忽略换行,只按制表符拆分所有字段。
内容的提问来源于stack exchange,提问作者Josh Brown
相关产品推荐
相关产品推荐

