简体   繁体   English

来自Scanner的java.util.NoSuchElementException

[英]java.util.NoSuchElementException from Scanner

I'm having trouble with my scanner when it's reading a file. 我的扫描仪正在读取文件时遇到问题。 It's suppose to make a new token when there's a comma followed by a space or when a new line is created, but after the 4 tokens, it throws the NoSuchElementException. 当有逗号后跟空格或创建新行时,假设创建一个新标记,但是在4个标记之后,它会抛出NoSuchElementException。

    private Map<String, Double> createElementMassMap(String filePath) {
    Map<String, Double> elementMap = new HashMap<>();
    try (Scanner sc = new Scanner(new FileReader(filePath))) {
        sc.useDelimiter(Pattern.compile("(, ) | (\r\n)"));
        sc.useLocale(Locale.US);
        while(sc.hasNext()) {
            String name = sc.next();
            System.out.println(name);
            double mass = sc.nextDouble();
            System.out.println(mass);
            elementMap.put(name, mass);
        }
    } catch (IOException e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(self, "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
    } 
    return elementMap;
}

Here's the file it's trying to read 这是它试图阅读的文件

H, 1.00
O, 16.00

and i made sure there isn't an empty line in the file. 我确保文件中没有空行。

Well im an idiot, my pattern was messed up. 我是一个白痴,我的模式搞砸了。

//instead of 
sc.useDelimiter(Pattern.compile("(, ) | (\r\n)"));
//it should be this
sc.useDelimiter(Pattern.compile("(, )|(\r\n)"));

thank you guys for the helpful answers though! 谢谢你们有用的答案!

What platform are you using? 你在用什么平台? The line separator differs from platform to platform. 行分隔符因平台而异。 Use this for supporting both(and of course remove the extra spaces surrounding the '|' in the regex). 使用它来支持两者(当然删除正则表达式中'|'周围的额外空格)。

            sc.useDelimiter("(, )|(\r\n)|(\n)");

I tried running this code on my computer like so: 我尝试在我的计算机上运行此代码,如下所示:

import javax.swing.JOptionPane;
import java.util.Scanner;
import java.util.Locale;
import java.util.regex.Pattern;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
import java.awt.Component;

public class Test {
    public static void main(String[] args) {
        createElementMassMap("file.txt");
    }

    private static Map<String, Double> createElementMassMap(String filePath) {
        Map<String, Double> elementMap = new HashMap<>();
        try (Scanner sc = new Scanner(new FileReader(filePath))) {
            sc.useDelimiter(Pattern.compile("(, ) | (\r\n) | (\n)"));
            sc.useLocale(Locale.US);
            while(sc.hasNext()) {
                String name = sc.next();
                System.out.println(name);
                System.out.println("hi");
                double mass = sc.nextDouble();
                System.out.println(mass);
                elementMap.put(name, mass);
            }
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog((Component)new Object(), "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
        }
        return elementMap;
    }
}

and what I got was 而我得到的是

H, 1.00
O, 16.00

hi
Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:862)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextDouble(Scanner.java:2413)
    at Test.createElementMassMap(Test.java:25)
    at Test.main(Test.java:13)

So, it looked like the first match matched the entire file. 所以,看起来第一场比赛与整个文件相匹配。 If you remove the spaces around the pipes: 如果删除管道周围的空格:

import javax.swing.JOptionPane;
import java.util.Scanner;
import java.util.Locale;
import java.util.regex.Pattern;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
import java.awt.Component;

public class Test {
    public static void main(String[] args) {
        createElementMassMap("file.txt");
    }

        private static Map<String, Double> createElementMassMap(String filePath) {
            Map<String, Double> elementMap = new HashMap<>();
            try (Scanner sc = new Scanner(new FileReader(filePath))) {
                sc.useDelimiter(Pattern.compile("(, ) | (\r\n) | (\n)"));
                sc.useLocale(Locale.US);
                while(sc.hasNext()) {
                    String name = sc.next();
                    System.out.println(name);
                    System.out.println("hi");
                    double mass = sc.nextDouble();
                    System.out.println(mass);
                    elementMap.put(name, mass);
                }
            } catch (IOException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog((Component)new Object(), "Error loading ElementMasses file.", "IOException", JOptionPane.ERROR_MESSAGE);
            }
            return elementMap;
        }
    }

The message disappears and it works perfectly 消息消失,完美无缺

I don't like scanner, and avaid it as much as I can. 我不喜欢扫描仪,尽可能多地使用扫描仪。 If yo want to try bufferedReader, here's the way to do it: 如果你想尝试bufferedReader,这是做到这一点的方法:

 BufferedReader in = new BufferedReader(new FileReader(filePath));
   StringTokenizer st;
   String line;

   try {
    while((line = in.readLine()) != null) {
           st = new StringTokenizer(line,", " );
           String name = st.nextToken();
           System.out.println(name);
           double mass = Double.parseDouble(st.nextToken());
           System.out.println(mass);
       }
} catch (Exception e) {
    // kaboom... something happened
    e.printStackTrace();
} 

EDIT: You can tweak the delimeter in StringTokenizer constructor to suit your needs 编辑:您可以在StringTokenizer构造函数中调整分隔符以满足您的需要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM