3

Я новичок в Java, и я пытаюсь использовать сканер для чтения в некоторых данных из текстового файла. Сканер читает в строковых и целочисленных элементах данных в порядке, но когда он достигает двойника, он генерирует исключение InputMismatchException.(Java) Сканер не читает в nextDouble() из файла

Формат текстового файла выглядит следующим образом ...

Фамилия, Имя, 0,0.0
Смит, Джон, 10,2.456
Джонс, Уильям, 15,3.568

Здесь мой код ...

import java.io.FileNotFoundException; 
import java.util.Scanner; 
import java.io.File; 

public class Student { 

    int age; 
    double gpa; 
    String firstName; 
    String lastName; 

    public static void main (String[] args) { 
     int iNum = 0; 
     double dNum = 0.0; 
     String str1 = ""; 
     String str2 = ""; 
     List<Student> listOfObjects = new ArrayList<>(); 

     try { 
      Scanner src = new Scanner(new 
        File("data.txt")).useDelimiter(",|\r\n|\n"); 

      while (src.hasNext()) { 
       str1 = src.next(); //last name 
       str2 = src.next(); //first name 
       iNum = src.nextInt(); //age 
       dNum = src.nextDouble(); /* gpa - having trouble reading these doubles with Scanner */    

       Student object = new Student(str1, str2, iNum, dNum); 
       listOfObjects.add(object); //add new object to list 

      } 
     } 
     catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

     for (Student a: listOfObjects) // printing the sorted list 
      System.out.print(a.getStudentLastName() + ", " + 
      a.getStudentFirstName() + 
      ", " + a.getStudentAge() + ", " + a.getStudentGpa() + "\n"); 
    } 

    public Student(String str1, String str2, int iNum, double dNum){ 
     this.lastName = str1; 
     this.firstName = str2; 
     this.age = iNum; 
     this.gpa = dNum; 
    } 

    public String getStudentFirstName() { 
     return firstName; 
    } 

    public String getStudentLastName() { 
     return lastName; 
    } 

    public int getStudentAge() { 
     return age; 
    } 

    public double getStudentGpa() { 
     return gpa; 
    } 

Я попытался установить локаль США и пытался баловаться с разделителями, но ничего, кажется, работает.

+0

@TimBiegeleisen Я пыталась дозвониться src.nextLine() после вызова src.nextDouble(), но ошибка все еще бросается. Я также пробовал читать его в виде строки и разбора в два раза, но такая же ошибка возникает. –

+0

Итак, следующий элемент не был двойным. – EJP

ответ

0

Большое спасибо @Sotirios за то, что он вызвал мое неправильное закрытие вопроса. Ваша проблема связана с использованием неправильного шаблона в вашем сканере. На основе фрагмента входного файла, который вы нам показали, есть пробелов после каждой запятой. Таким образом, вы должны использовать следующий шаблон, чтобы отразить это:

,\\s*|\r\n|\n 
^^^^^ match a comma, followed by zero or more spaces 

Когда я тестировал на местном уровне, я даже не получить как значения double, он разбился при чтении третьего позиционного целого. Попробуйте следующий код:

Scanner src = new Scanner(new File("data.txt")).useDelimiter(",\\s*|\r\n|\n"); 
while (src.hasNext()) { 
    str1 = src.next(); 
    str2 = src.next(); 
    iNum = src.nextInt(); 
    dNum = src.nextDouble(); 

    Student object = new Student(str1, str2, iNum, dNum); 
    listOfObjects.add(object); //add new object to list 
} 

Причина первые две строки получали через то, что пространство после запятая была быть свернута в следующей строке. Но вам не избежать этого с числами, и в этом случае лишних пробелов было некуда, и вы закончили с InputMismatchException, которые вы видели.

+0

Извините, я обновил сообщение, чтобы показать, что после запятых нет пробелов. Это была опечатка с моей стороны. Я все равно пробовал этот шаблон в любом случае, безрезультатно. –

+0

Тогда я не могу воспроизвести вашу проблему локально. Вы должны работать над тем, чтобы сделать вашу проблему воспроизводимой, чтобы другие могли ее решить. –

+0

Сколько строк ввода вы можете прочитать, или вы даже не можете прочитать одну полную строку? –

0

Я решил проблему. Используемый множитель разделителя выглядел так («, | \ r \ n | \ n»). Таким образом, сканер не видел двойной, но вместо этого включал его в строку с фамилией, разделенной каретой возврата.

Простым решением для этого было включение возврата каретки в шаблон.

Новая модель выглядит следующим образом - ("| \ г \ п | \ п | \ г")

Смежные вопросы