2015-10-27 1 views
1

Я хочу, чтобы прочитать файл, который имеет следующий вид:Java Scanner - два разделителей и исключение

c00004;Doe John;bananas;4.0;50.0 
c00003;Doe John;milk;4.0;5.0 
c00001;Doe John;milk;4.0;10.0 
c00001;Doe John;milk;5.0;2.0 

И с этим кодом:

Scanner in = new Scanner(Paths.get(fileName)); 
in.useDelimiter(";|\\s"); 

while(in.hasNext()) 
{ 
    String customerID = in.next(); 
    String surname = in.next(); 
    String firstName = in.next(); 
    String productName = in.next(); 
    double price = in.nextDouble(); 
    double quantity = in.nextDouble(); 

    Purchase newPurchase = new Purchase(customerID, surname, firstName, productName, price, quantity); 
} 

in.close(); 

я получаю Input несовпадение Exception в середине чтения второй строки данных. Есть идеи, почему?

EDIT: Если I выход каждой переменной, прочитав его, выход:

c00004 Doe John bananas 4.0 50.0 
c00003 Doe John Exception in thread "main" java.util.InputMismatchException 
    at java.util.Scanner.throwFor(Scanner.java:864) 
    at java.util.Scanner.next(Scanner.java:1485) 
    at java.util.Scanner.nextDouble(Scanner.java:2413) 
    at CustomersPurchaseSortFind.readFile(CustomersPurchaseSortFind.java:31) 
    at Main.main(Main.java:9) 
+0

Вы можете разместить свой StackTrace? –

+0

@JordiCastilla Я обновил сообщение. – Quentin

+0

Ну, слишком плохо, что вы на Windows, потому что у вас не будет этой проблемы в Unix-System: P. Но у вас уже есть ответ с решением. – Tom

ответ

2

Ваше регулярное выражение должно быть:

in.useDelimiter(";|\\s+"); 

потому что ваши данные имеют \r в Окно с новой строкой \n в конце линии, во втором цикле, разделитель будет включать в себя \r символа в качестве элемента:

int i = 1; 
    while(in.hasNext()) 
    { 
     System.out.println("line: " + i++); 
     String customerID = in.next(); 
     String surname = in.next(); 
     String firstName = in.next(); 
     String productName = in.next(); 
     double price = in.nextDouble(); 
     System.out.println("Price: " + price); 
     double quantity = in.nextDouble(); 
    } 

Выхода:

line: 1 
customerID: c00004 
Price: 4.0 
line: 2 
customerID: 
Exception in thread "main" java.util.InputMismatchException 
    at java.util.Scanner.throwFor(Scanner.java:909) 
    at java.util.Scanner.next(Scanner.java:1530) 
    at java.util.Scanner.nextDouble(Scanner.java:2456) 
    at Test.main(Test.java:32) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 

исключения актуально бросил вторым циклом для синтаксического разбора.

мы можем видеть, второй customerID пуст.

и для второго цикла Цена значение составляет: milk, поэтому он будет throwInputMismatchException для Double parse

+0

Решение правильное, но объяснение неточно. Пожалуйста, перепроверьте то, что вы написали, и почему он терпит неудачу. – Tom

2

В качестве альтернативы просто прочитать всю строку затем использовать раскол:

String nextLine=in.nextLine(); 
String[] splitted= nextLine.split(";|\\s"); 
+1

'\\ s' уже включает' \\ n': http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html – Tom

+0

@ Хороший партнер, thx. Я удалю первую часть ответа, я все же верю, что читая целую линию, расщепление является самым простым и безопасным способом. поэтому я сохраняю эту часть как часть ответа – nafas

+0

Тогда вам нужно только исправить вызов метода на 'in'; P. – Tom