TL; DR Sử dụng scanner.skip("\\R")
trước mỗi scanner.newLine()
cuộc gọi, được thực hiện sau:
scanner.next()
scanner.next*TYPE*()
phương pháp.
Những điều bạn cần biết:
văn bản đại diện cho một vài dòng cũng chứa các ký tự không in được giữa các dòng (chúng tôi gọi chúng là dấu phân cách dòng) như
- lợi nhuận vận chuyển (CR - theo chuỗi ký tự đại diện là
"\r"
)
- nguồn cấp dữ liệu (LF - theo chuỗi ký tự đại diện là
"\n"
)
Khi bạn đang đọc dữ liệu từ bảng điều khiển, nó cho phép người dùng nhập phản hồi của anh ta và khi anh ta hoàn thành, anh ta cần phải xác nhận bằng cách nào đó . Để làm như vậy, người dùng được yêu cầu nhấn phím "enter" / "return" trên bàn phím.
Điều quan trọng là khóa này bên cạnh việc đảm bảo đặt dữ liệu người dùng vào đầu vào tiêu chuẩn (được đại diện bởi System.in
nó được đọc bởi Scanner
) cũng gửi các dấu tách dòng phụ thuộc HĐH (như cho Windows\r\n
) sau nó.
Vì vậy, khi bạn hỏi người dùng về giá trị như thế nào age
, và người dùng gõ 42 và nhấn enter, đầu vào tiêu chuẩn sẽ chứa "42\r\n"
.
Vấn đề
Scanner#nextInt
(và các phương pháp khác ) không cho phép Máy quét sử dụng các dải phân cách này. Nó sẽ đọc chúng từ (làm thế nào khác Máy quét sẽ biết rằng không có nhiều chữ số từ người dùng đại diện cho giá trị hơn so với khoảng trắng?) Sẽ xóa chúng khỏi đầu vào tiêu chuẩn, nhưng nó cũng sẽ lưu trữ các dấu tách dòng đó bên trong . Điều chúng ta cần nhớ là tất cả các phương thức Scanner luôn được quét bắt đầu từ văn bản được lưu trong bộ nhớ cache. Scanner#nextType
System.in
age
Bây giờ Scanner#nextLine()
chỉ cần thu thập và trả về tất cả các ký tự cho đến khi tìm thấy dấu phân cách dòng (hoặc cuối luồng). Nhưng vì các dấu tách dòng sau khi đọc số từ bảng điều khiển được tìm thấy ngay lập tức trong bộ đệm của Máy quét, nó trả về Chuỗi trống, có nghĩa là Máy quét không thể tìm thấy bất kỳ ký tự nào trước các dấu tách dòng đó (hoặc cuối luồng).
BTW nextLine
cũng tiêu thụ những dải phân cách.
Giải pháp
Vì vậy, khi bạn muốn xin số và sau đó cho toàn bộ dòng trong khi tránh chuỗi trống đó là kết quả của nextLine
, một trong hai
- tiêu thụ phân tách dòng còn lại
nextInt
từ bộ đệm Bộ quét
- gọi
nextLine
,
- hoặc IMO cách dễ đọc hơn sẽ bằng cách gọi
skip("\\R")
hoặc skip("\r\n|\r|\n")
để Máy quét bỏ qua phần khớp với dấu phân cách dòng (thông tin thêm về \R
: https://stackoverflow.com/a/31060125 )
- không sử dụng
nextInt
(cũng không next
, hoặc bất kỳ nextTYPE
phương pháp nào ). Thay vào đó, hãy đọc toàn bộ dữ liệu từng dòng bằng cách sử dụng nextLine
và phân tích số từ mỗi dòng (giả sử một dòng chỉ chứa một số) thành loại thích hợp như int
thông qua Integer.parseInt
.
BTW : các phương thức có thể bỏ qua các dấu phân cách (theo mặc định tất cả các khoảng trắng như tab, dấu phân cách dòng) bao gồm cả các bộ nhớ cache của máy quét, cho đến khi chúng sẽ tìm thấy giá trị không phân cách tiếp theo (mã thông báo). Nhờ đó cho đầu vào như mãScanner#nextType
"42\r\n\r\n321\r\n\r\n\r\nfoobar"
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
sẽ có thể chỉ định đúng num1=42
num2=321
name=foobar
.