30/09/2018, 17:18

[Java] Scanner.nextLine() không dừng lại để nhập vào

Mình đang bắt đầu học java. Có lỗi này thỉnh thoảng gặp phải nhưng không rõ nguyên nhân do đâu.
Ví dụ mình có đoạn code bên dưới - phương thức nhập vào thông tin SV và lưu vào danh sách.

private void input() {
	// Nhap so luong SV trong danh sach
	System.out.print("    So luong sinh vien can nhap vao: ");
	Scanner keyboard = new Scanner(System.in);
	int N = keyboard.nextInt();

	// Nhap thong tin
	for (int i = 1; i <= N; i++) {
		String ten, diaChi, ID;
		int tuoi;
		float toan, ly, hoa;

		System.out.println("    
Nhap thong tin cho sinh vien thu " + i);
		System.out.print("	Ho va ten: ");
		ten = keyboard.nextLine();

		System.out.print("	Tuoi: ");
		tuoi = keyboard.nextInt();

		System.out.print("	Dia chi: ");
		diaChi = keyboard.nextLine();
		keyboard.nextLine();

		System.out.print("	ID: ");
		ID = keyboard.nextLine();

		System.out.print("	Diem toan: ");
		toan = keyboard.nextFloat();

		System.out.print("	Diem ly: ");
		ly = keyboard.nextFloat();

		System.out.print("	Diem hoa: ");
		hoa = keyboard.nextFloat();

		// Khoi tao doi tuong sinh vien
		// Luu thong tin vua nhap vao doi tuong
		Student st = new Student(ten, tuoi, diaChi, ID, toan, ly, hoa);

		// Luu doi tuong vao list
		list.add(st);
	}
	System.out.println("
--------
");
}

Màn hình console của mình nó lại chạy như thế này:

**CHUONG TRINH QUAN LY SINH VIEN**
1. Nhap gia tri cho danh sach sinh vien
2. Sap xep sinh vien theo chieu tang dan diem TB
3. Tim sinh vien co diem toan lon nhat
4. Hien thi nhung sinh vien tren 23 tuoi
5. Tim cac sinh vien ho 'Huynh'
6. Tim cac sinh vien co dia chi o DN
7. Thoat
---------
Nhap so de chon chuc nang: 1
    So luong sinh vien can nhap vao: 5
    
Nhap thong tin cho sinh vien thu 1
	Ho va ten: dai son
	Tuoi: 23
	Dia chi: hue
	ID: 11
	Diem toan: 10
	Diem ly: 9
	Diem hoa: 9.5
    
Nhap thong tin cho sinh vien thu 2
	Ho va ten: 	Tuoi: 20    //Error here
	Dia chi: dm
	ID: 12
	Diem toan: 9
	Diem ly: 7
	Diem hoa: 6.5
    
Nhap thong tin cho sinh vien thu 3
	Ho va ten: 	Tuoi: 24        //Error here
	Dia chi: am
	ID: 14
	Diem toan: 8
	Diem ly: 7
	Diem hoa: 9

Để ý ở lần nhập thứ 2 trở đi, chương trình ko dừng để nhập tên, mà nhảy thẳng sang dòng nhập tuổi.
Mình chưa rõ về cái phương thức Scanner này, mong anh em trên diễn đàn giải thích thêm.

Ice Tea viết 19:18 ngày 30/09/2018

Kết thúc lần đọc thứ nhất, do ở dòng hoa = keyboard.nextFloat(); nó chỉ đọc số mà bạn nhập cả số và ký tự newline “\n” (phím Enter) nên vẫn còn thừa 1 ký tự “\n” trong input, vì thế khi vào lần đọc thứ 2 nó đọc ký tự “\n” trong input luôn.

Phương pháp:

  • Cách 1: Gọi tiếp lệnh keyboard.nextLine(); ở giữa hai lệnh đọc số và đọc string.
  • Cách 2: Coi tất cả input là String, chỉ dùng keyboard.nextLine(); để đọc, cái nào là số thì convert sang số.
Mai Anh Dũng viết 19:25 ngày 30/09/2018

Trả lời của Diệu Minh Trần


Thêm keyboard.nextLine(); vào sau int N = keyboard.nextInt(); và sau hoa = keyboard.nextFloat();

Vì sau những method nextInt() hay nextFloat(), chúng ta input giá trị vào, kí tự Enter vẫn còn trong bộ đệm và được đọc vào những phương thức nhập tiếp theo nên phải ignore nó đi

Đỗ Trung Quân viết 19:29 ngày 30/09/2018
keybroad.nextLine();
ten = keyboard.nextLine();
Quân viết 19:29 ngày 30/09/2018

Đây là hiện tượng trôi lệnh giống như khi bạn dùng scanf trong c ấy. Hình như mình có nói một lần rồi nhưng không nhớ link.

Khi nhập tuổi là bạn nhập 1 số và 1 cái phím enter, enter nó không được đọc vì nó là ký tự mà đưa vào bộ đệm, khi nhập tên, máy đọc trong bộ đệm xem có cái gì phù hợp với kiểu của tên (chuỗi) và nó lấy luôn cái enter đó.
Để khắc phục bạn không nhập số bằng keyboard.nextInt();, keyboard.nextDouble();… mà dùng cách sau: tuoi = integer.pareInt(keyboard.nextLine());
Cách hoạt động là nó đọc 1 dòng chuỗi trước (bao gồm cả phím enter) sau đó chuyển chuỗi đọc được sang dạng số nguyên. Nếu dùng double thì là số thực.

Phúc Nguyễn viết 19:28 ngày 30/09/2018

nextLine() + “\n” thì sẽ xuống dòng để đọc tiếp thì phải

Người bị bơ viết 19:23 ngày 30/09/2018

Mình có thắc mắc giống bạn này nhưng giờ đã giải quyết được bằng 2 cách:
Cách 1: Theo anh @ltd thì thêm keyboard.nextFloat(); vào sau nextInt() để loại bỏ giá trị bị dư thừ.
Cách 2: Mình sữa cái ten = keyboard.nextLine(); thành ten = keyboard.next(); thì nó không bị lỗi và tại sao nó không nhận giá trị dư thừa là nút Enter như anh @ltd nói?

Sơn Trần viết 19:21 ngày 30/09/2018

Bạn nói ngược hết

  • Thêm .nextLine() vào sau .nextInt() chứ .nextFloat() thì cũng không nhận ký tự enter.
  • keyboard.nextLine() thì không xảy ra lỗi gì cả, hàm này nó đọc hết cả câu lẫn dấu enter.
Người bị bơ viết 19:33 ngày 30/09/2018

Oh mình xin lỗi mình viết nhầm, phải là .nextLIne() vào sau .nextInt() và .nextFloat() vì nó không nhận ký tự Enter.(Thông cảm đi ha trời hơi nóng )
Mình có bài toán như thế này:

public class Bt1 {
public static void main(String[] agrs){
    String HoTen[];
    int a;
    Scanner input = new Scanner(System.in);
    System.out.print("Nhập số sinh viên: ");
    a = input.nextInt();
    HoTen = new String[a]; 
    for(int i=0;i<HoTen.length;i++){
        System.out.print("Nhập tên sinh viên thứ "+(i+1)+" ");
        HoTen[i]= input.nextLine();
    }
}

Khi mình chạy thì do lần nhập đầu tiên còn thừa từ đó được nhập vào lần tiếp theo tức “Nhập tên sinh viên thứ 1”. Nhưng nếu mình thây HoTen[i]= input.nextLine(); --> HoTen[i]= input.next(); thì sao lần “Nhập sinh viên thứ 1” lại không bị bỏ qua vì nhận giá trị dư thừa từ lần nhập thứ nhất như nextLine?
Thì mình mới test lại thử và biết là next() thì nó không chấp nhận Enter là một giá trị mà bắc buộc phải có thêm ký tự khác, còn nextLine() thì nó chấp nhận Enter là một giá trị cho nên nó nhảy sang cái tiếp theo.

Nguyen Thanh Hải viết 19:23 ngày 30/09/2018

Em muốn bắt một ký tự vào và không cần enter thì phải làm sao vậy mọi người?
thanks!!!

Mai Anh Dũng viết 19:24 ngày 30/09/2018

Topic này cả năm rồi mà giờ còn đào lên :’(

Huy Bình viết 19:28 ngày 30/09/2018

Tạo 1 biến Scanner mới rồi gán biến Scanner đó cho biến mình muôn nhập vào.

Bài liên quan
0