简体   繁体   中英

Implementing a while loop inside a try-catch method in Java

So basically what I'm trying to do with my code is look through a payroll.txt file looking like this:

31718 PHILLIP LENNOX 55.0 20.00
11528 NANCY TROOPER 40.0 10.45
16783 JOHN CONNAUGHT 30.5 10.00
10538 PETER DUNCAN 45.0 10.75
21O15 JAMES HAROLD 32.0 10.50
61326 HARRY KUHN 25.0 12.30
82465 MICHELLE BENOIT 50.0 18.50
31816 DANIELLE RAYMOND 35.5 15.25
73745 JACK O'TOOLE 28.0 11.50

And pick up InputMismatchExceptions or a double that's lower than 10.35 (As seen in my code below) and print out that whole line in another file called payrollError.txt. The problem I'm getting here is basically this prints to my payrollError.txt file:

31718 PHILLIP LENNOX 55.0 20.0
11528 NANCY TROOPER 40.0 10.45
10538 PETER DUNCAN 45.0 10.75
0 null null 0.0 0.0
0 null null 0.0 0.0
0 null null 0.0 0.0
0 null null 0.0 0.0
0 null null 0.0 0.0
(These lines go on infinitely)

And I can't seem to figure out the problem. I've tried various different methods but get no out prints at all, or this massive infinite printout.

  import java.io.*;
    import java.util.*;

public class Main {
public static void main(String[] args){

    List<Employee> ArrEmployee = new ArrayList<>(); //  array for employee objects

        try (PrintWriter txtOut = new PrintWriter("payrollError.txt")) {

            Scanner txtIn = new Scanner(new File("payroll.txt")); 

            while (txtIn.hasNext()) { // looping through the payroll.txt file and creating Employee objects from its data
                 long EmployeeNumber = 0;
                 String EmployeeName = null;
                 String LastName = null;
                 double HoursWorked = 0;
                 double HourlyWage = 0;

                 try{
                      EmployeeNumber = txtIn.nextLong();
                      EmployeeName = txtIn.next();
                      LastName = txtIn.next();
                      HoursWorked = txtIn.nextDouble();
                      HourlyWage = txtIn.nextDouble();

                        if (HourlyWage > 10.35){ 
                            throw new MinimumWageException(); // throws exception if the hourly wage is less than 10.35$
                                }

                        else
                            ArrEmployee.add(new Employee(EmployeeNumber,EmployeeName,LastName,HoursWorked,HourlyWage)); // creates Employee objects according to the input payroll.txt
                }
                catch (InputMismatchException n) { // catching long,strings and doubles in the payroll.txt that aren't valid
                     txtOut.println(EmployeeNumber + " " + EmployeeName + " " + LastName + " " + HoursWorked + " " + HourlyWage);
                     txtIn.hasNext();

                     }
                 catch (MinimumWageException z){
                     txtOut.println(EmployeeNumber + " " + EmployeeName + " " + LastName + " " + HoursWorked + " " + HourlyWage);
                     txtIn.hasNext();
                 }
                      }


        } catch (FileNotFoundException e) {
            System.out.println("File payroll.txt was not found.");

            }

    }

}

You have a few issues here. One already pointed out is that you have (HourlyWage > 10.35) instead of (HourlyWage < 10.35) . The main problem is that after you encounter the input mismatched caused by having the letter "O" instead of the number 0 in 21O15 , the scanner leaves the token in the stream. That's why you get into the infinite loop. You keep reading the bad input over and over. Of course none of the variables like EmployeeName etc. get assigned a value, which is why you see the 0's and nulls being printed from the catch block.

To fix the infinite loop, you need to eat the rest of the line before going back to the top of the loop. Note the txtIn.nextLine() instead of the txtIn.hasNext() you had before. (I'm not sure why you have txtIn.hasNext() in your catch blocks.)

catch (InputMismatchException n) { // catching long,strings and doubles in the payroll.txt that aren't valid
    txtOut.println("IME: " + EmployeeNumber + " " + EmployeeName + " " + LastName + " " + HoursWorked + " " + HourlyWage);
    txtIn.nextLine()
}

EDIT
To work around the problem of not having read in the values you're trying to print in the catch block, you can print the ones that were successfully read followed by the rest of the line retrieved by nextLine() :

            catch (InputMismatchException n) { // catching long,strings and doubles in the payroll.txt that aren't valid
                StringBuilder sb = new StringBuilder();
                sb.append(EmployeeNumber == 0 ? "" : (EmployeeNumber + " "));
                sb.append(EmployeeName == null ? "" : (EmployeeName + " "));
                sb.append(LastName == null ? "" : (LastName + " "));
                sb.append(HoursWorked == 0.0 ? "" : (HoursWorked + " "));
                sb.append(HourlyWage == 0.0 ? "" : (HourlyWage + " "));
                sb.append(txtIn.nextLine());
                txtOut.println(sb.toString());
            }

It's not perfect because 0.0 could be a legal value for hours worked, eg, but maybe it's good enough for your purposes. In any case, one problem at a time :)

You should take a look at the documentation for the Scanner class. It says that

When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.

That means, that instead of calling hasNext() in the catch block, you should call skip()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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