1

ユーザー定義クラスの2つのオブジェクトに対してクラス Scanner の1つのオブジェクトを使用する場合。コンパイラは、一部の入力取得行をスキップします。後述のとおりです。

1) Scanner obj = new Scanner(System.in);

2) GradeBook book1 = new GradeBook();
3) GradeBook book2 = new GradeBook();

//input for book1

4) variable1 = obj.nextInt();
5) book1.variable1 = variable1;
6) variable2 = obj.nextInt();
7) book1.variable1 = variable2;
8) variable3 = obj.nextInt();
9) book1.variable1 = variable3;

//input for book2

10) variable1 = obj.nextInt();
11) book2.variable1 = variable1;
12) variable2 = obj.nextInt();
13) book2.variable1 = variable2;
14) varibale3 = obj.nextInt();
15) book2.variable1 = variable3;

行番号 10 をスキップします (この行は読みませんvariable1 = obj.nextInt();)。

しかし、Book1 用と book2 用の Scanner クラスの 2 つの異なるオブジェクトを使用すると、正常に動作します。

問題は何ですか、なぜこのようなことが起こるのですか?

import java.util.Scanner;
public class GradeTest {

    /**
     * @param args
     */ 
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        try{
        Employee employee1 = new Employee();
        Employee employee2 = new Employee();

        String fName,lName;
        double salary;              

        System.out.print("Enter first name:");
        fName = input.nextLine();
        employee1.SetFName(fName);
        System.out.print("\nEnter last name:");             
        lName = inp.nextLine();
        employee1.SetLName(lName);
        System.out.print("\nEnter salary:");
        salary = inp.nextDouble();
        employee1.SetSalary(salary);

        System.out.printf("\n1:Updated Value \n FName : %s  LName : %s  Salary : %.2f ", employee1.GetFName(),employee1.GetLName(),employee1.GetSalary());

Systm.out.println("Enter data for second employee. \n");

        System.out.print("Enter first name:");
        lName = input.nextLine();
        employee2.SetFName(fName);
        System.out.print("\nEnter last name:");
        lName = input.nextLine();
        employee2.SetLName(lName);
        System.out.print("\nEnter salary:");
        salary = input.nextDouble();
        employee2.SetSalary(salary);

            System.out.printf("\n2:Initial Value \n FName : %s  LName : %s  Salary : %.2f ", employee2.GetFName(),employee2.GetLName(),employee2.GetSalary());
                }
        finally{
                inp.close();
        }
    }
}

期待される出力:

Enter first name: First Name1
Enter last name:  Last Name1                
Enter salary: 1500.00

Enter data for second employee.

Enter first name: First Name2
Enter last name:  Last Name2                
Enter salary: 1200.00

実際の出力:

Enter first name: First Name1
Enter last name:  Last Name1                
Enter salary: 1500.00

Enter data for second employee.

Enter first name: 
Enter last name:  Last Name2                
Enter salary: 1200.00
4

1 に答える 1

2

これは、実際には設計どおりに動作するスキャナです。仕組みは次のとおりです。

next() は、ストリームから区切り文字 (デフォルトでは空白) の次のインスタンスまでの入力を受け取り、区切り文字をそのままにします。nextLine() は、次の「\n」文字まで取り、改行を破棄して、ゼロの場合もある残りを返します。

したがって、next() に続いて nextLine() を実行し、ユーザーが next() 呼び出しでトークンを 1 つだけ入力した場合、ストリームに残るのは、next() が実行しない「\n」文字になります。取った。次に、nextLine() は、唯一のものである "\n" まで取り、"\n" を捨てて "" を返します。

それは紛らわしい実装です、私は知っています。

tl;dr: nextLine() を使用して、next() の後にクリアします。

注: nextInt() は、next() の呼び出しとそれに続く parseInt() にすぎないため、この点に関しては next() とまったく同じように動作します。

于 2013-07-16T19:40:12.477 に答える