0

メソッド updateEmployees(PersonnelManager pm) はテキスト ファイルを読み取り、ファイルの各行の最初の文字 (3 つの可能性があります) に応じて、異なるコードを実行します。PersonnelManager クラスと Employee クラスは問題に関与していません。そのため、ここではそれらを含めません。サンプル入力ファイルは次のとおりです。

n メザリラ、ルーカス h 40000

r5

キンゼイ

n プライス、レーン s 50

r4

メソッドは次のとおりです: (File オブジェクトと Scanner オブジェクトはメソッドの外で宣言されます)

public static boolean updateEmployees(PersonnelManager pm) {
    
    try 
    {
    file = new File(updates);
    in = new Scanner(file);
    }
    
    catch (FileNotFoundException e) 
    {
        System.out.println("Could not load update file.");
        return false;
    }
    
    int currentLine = 1; //Keep track of current line being read for error reporting purpose
    while (in.hasNext()) {
        String line = in.nextLine();
        
        //Check the type of update the line executes
        
        //Update: Add new Employee
        if (line.charAt(0) == 'n') {
    
            String[] words = line.split("\\s"); //Split line into words. Index [0]: update type.  [1]: last name.   [2]: first name.   [3]: employee type.  [4]: wage.
            words[1] = words[1].substring(0, words[1].length() - 1); //remove comma from last name
    
            if (words.length != 5) { //If there are not 5 words or tokens in the line, input is incorrect.
                System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
                return false; 
            }
            
            if (words[3].equals("s"))  //if employee is type SalariedEmployee
                pm.addEmployee(new SalariedEmployee(words[2], words[1], Double.parseDouble(words[4])));
            
            
            else if (words[3].equals("h"))  //if employee is type HourlyEmployee
                pm.addEmployee(new HourlyEmployee(words[2], words[1], Double.parseDouble(words[4])));
            
            else {
                System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
                return false;
            }
            //Display information on the console
            System.out.println("New Employee added: " + words[1] + ", " + words[2]);
        }
        
        //Update: Raise rate of pay
        if (line.charAt(0) == 'r') {
            String[] words = line.split("\\s"); //Split line into words. Index [0]: update type.  [1]: rate of wage raise
            if (Double.parseDouble(words[1]) > 100.0) { //If update value is greater than 100
                System.out.println("Error in line:" + currentLine + ". Wage raise rate invalid.");
                return false;
            }
            
            for (int i =0; i<pm.howMany(); i++) { //Call raiseWages() method for all employees handled by the pm PersonnelManager
                pm.getEmployee(i).raiseWages(Double.parseDouble(words[1]));
            }
            
            //Display information on the console
            System.out.println("New Wages:");
            pm.displayEmployees();
            
        }
        
        //Update: Dismissal of Employee
        if (line.charAt(0) == 'd') {
            String[] words = line.split("\\s"); //Split line into words. Index [0]: update type.  [1]: last name of employee
            if (words.length != 2) { //If there are not 2 words or tokens in the line, input is incorrect.
                System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
                return false; 
            }
            
            String fullName = pm.getEmployee(words[1]).getName(); //Get complete name of Employee from last name
            pm.removeEmployee(words[1]);
            
            //Display information on the console
            System.out.println("Deleted Employee: " + fullName);
        }
        
        currentLine++;
    }
    return true;
}

入力ファイルには 5 行あるので、while ループは 5 回実行されるはずですが、そうはなりません。入力ファイルの 4 行目「n Pryce, Lane s 50」に到達すると、コードの 25 行目で「java.lang.StringIndexOutOfBoundsException」エラーが発生します。

問題は 24 行目と 25 行目で発生します。

String[] words = line.split("\\s"); //Split line into words. Index [0]: update type.  [1]: last name.   [2]: first name.   [3]: employee type.  [4]: wage.
words[1] = words[1].substring(0, words[1].length() - 1); //remove comma from last name

入力の 4 行目では、"line" 文字列が 5 つの文字列に分割されていません。これはwords[0]にあり、「n」に等しい1つにのみ分割されます。私が理解できないのは、プログラムが同じコード行を使用して、入力の最初の 3 行の文字列を分割したことです。4 行目で機能しないのはなぜですか?

入力ファイルを次のように変更すると

n メザリラ、ルーカス h 40000

r5

キンゼイ

コマンド「n」の2番目の出現を削除すると、機能します。実際、同じコマンド (「n」、「r」、または「d」) を複数回使用する入力ファイルを使用するたびに、コマンドが 2 回目に発生する行は 1 つの文字列にのみ分割されます。行の最初のトークン (int この場合は "n"、"r"、または "d") を含みます。

説明が明確だったことを願っています。なぜこれが起こるのか知っている人がいたら、助けてください。

4

1 に答える 1