Что плохого в чтении моего файла с помощью класса Scanner? - PullRequest
0 голосов
/ 22 января 2020

Каждый раз, когда я запускаю его, выдает это сообщение ((InputMismatchException)), откуда проблема?

        File f = new File("nameList.txt");
    try {
        PrintWriter out;
        out = new PrintWriter(f);
        for (int i = 0; i < 4; i++) {
            out.printf("Name : %s Age : %d ", "Rezaee-Hadi", 19);
            out.println("");
        }
        out.close();
    } catch (IOException ex) {
        System.out.println("Exception thrown : " + ex);
    }
    try {
        Scanner in = new Scanner(f);
        String name = in.nextLine();
        int age = in.nextInt();
        for (int i = 0; i < 4; i++) {
            System.out.println(name);
            System.out.println(age);
        }
        in.close();
    } catch (FileNotFoundException ex) {
        System.out.println("Exception thrown : " + ex);
    }

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Вы создаете свой файл данных в следующем формате данных:

Name : Rezaee-Hadi Age : 19

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

Rezaee-Hadi, 19

Если вы хотите, вы можете поместить заголовок в качестве самой первой строки файла данных, чтобы можно было легко определить, к чему относится каждый фрагмент данных в каждой строке. например:

Name, Age
Rezaee-Hadi, 19
Fred Flintstone, 32
Tom Jones, 66
John Smith, 54

На самом деле это типичный формат файлов данных CSV.

Сохранение формата данных файла, который вы уже используете:

Нет ничего плохого в использовании метода Scanner # nextLine () . Это хороший способ для go, но вы должны перебирать файл по строке, используя , а l oop, потому что вы не всегда можете точно знать, сколько фактических строк данных содержится в файле, например:

Scanner in = new Scanner(f);
String dataLine;
while (in.hasNextLine()) {
    dataLine = in.nextLine().trim();
    // Skip Blank Lines
    if (dataLine.equals("")) {
        continue;
    }
    System.out.println(dataLine);
}

Это напечатает все строки данных, содержащиеся в вашем файле. Но это не то, что вы действительно хотите, это. Вы хотите отделить имя и возраст от каждой строки, что означает, что вам нужно проанализировать данные из каждой строки. Один из способов (в вашем случае) будет выглядеть примерно так:

String dataLine;
Scanner in = new Scanner(f);
while (in.hasNextLine()) {
    dataLine = in.nextLine().trim();
    // Skip Blank Lines
    if (dataLine.equals("")) {
        continue;
    }
    String[] dataParts = dataLine.replace("Name : " , "").split(" Age : ");
    System.out.println("The Person's Name: " + dataParts[0] + System.lineSeparator() 
                     + "The Person's Age:  " + dataParts[1] + System.lineSeparator());
}

В приведенном выше коде мы перебираем весь файл данных по одной строке за раз, используя , тогда как l oop. Поскольку каждая строка считывается в строковую переменную dataLine , она также обрезается от любых начальных или конечных пробелов. Обычно мы не хотим этого. Затем мы проверяем, чтобы строка не была пустой. Как правило, они нам тоже не нужны, и здесь мы пропускаем эти пустые строки, выдав continue to while l oop, чтобы немедленно инициировать еще одну итерацию. Если строка строки файла действительно содержит данные, то она хранится в переменной dataLine .

Теперь мы хотим проанализировать эти данные, чтобы получить имя и возраст и поместить их в массив строк. Мы делаем это с помощью метода String # split () , но сначала мы избавляемся от части строки Name: , используя String # replace () метод, так как мы не хотим иметь дело с этим текстом, пока мы анализируем строку. В методе String # split () мы предоставляем разделитель строк для разделения, и этот разделитель равен " Age: ".

String[] dataParts = dataLine.replace("Name : " , "").split(" Age : ");

Теперь, когда каждая строка анализируется, имя и возраст будут содержаться в строковом массиве dataParts [] как элементы, расположенные по индексу 0 и индексу 1. Теперь мы используем эти элементы массива для отображения результатов в окне консоли.

На этом этапе Age - это строка , расположенная в массиве dataParts [] с индексом 1 , но вы можете преобразовать этот возраст в целое число (int) значение типа. Для этого вы можете использовать методы Integer.parseInt () или Integer.valueOf () , но перед этим вам следует проверить факт передачи строки, которую вы собираетесь передать любой из этих методов действительно является строковым числовым целочисленным значением. Для этого вы должны использовать метод String # match () вместе с простым небольшим Регулярным выражением (RegEx):

int age = 0;
if (dataParts[1].matches("\\d+")) {
    age = Integer.parseInt(dataParts[1]);
    // OR  age = Integer.valueOf(dataParts[1]);
    System.out.println("Age = " + age);  
}
else {
    System.out.println("Age is not a numerical value!");  
}

Регулярное выражение "\\d+" помещенный в метод String # match () в основном означает: "Является ли предоставленная строка строковым представлением целочисленного числового значения?". Если метод обнаруживает, что это не так, возвращается логическое значение false . Если он находит, что предоставленное значение является строковым целым числовым значением, то возвращается логическое значение true . Выполнение этих действий предотвратит возникновение NumberFormatException .

0 голосов
/ 22 января 2020

Замените это:

        int age=0;
        while (in.hasNext()) {

            // if the next is a Int,
            // print found and the Int
            if (in.hasNextInt()) {
                 age = in.nextInt();
                System.out.println("Found Int value :"
                        + age);
            }
        }

вместо этого:

  int age = in.nextInt();

Тогда вы больше не получите «InputMismatchException» ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...