2015-11-11 15 views
8

Tôi đang học JAVA và gõ DO sau đây ... Ví dụ. Chương trình sẽ bỏ nếu tôi gõ 'q'. Nó chạy nhưng tại sao tôi nhận được ba hàng của "Xin vui lòng một chìa khóa tiếp theo ENTER:"?Một java rất đơn giản ... trong khi vòng lặp

class DWDemo { 
    public static void main (String args[]) 
     throws java.io.IOException { 
      char ch; 
      do { 
       System.out.println("Please a key followed by ENTER:"); 
       ch = (char) System.in.read(); 
      } while (ch != 'q'); 
     } 
} 

enter image description here

Trả lời

10

Bởi vì khi bạn gõ a và nhấn Enter, sau đó phương pháp in.read() trả về ba nhân vật - 'a', nhân vật cho vận chuyển trở lại \r và nhân vật cho ngắt dòng ('\n'). (Lưu ý rằng kết hợp \r\n được coi là ngắt dòng trong Windows).

Chương trình của bạn sẽ có hành vi khác biệt đáng kể nếu bạn chạy nó dưới Linux hoặc OSX, vì ký tự ngắt dòng là đặc trưng cho hệ điều hành bạn đang chạy chương trình. Trong Linux, nó sẽ là \n, trong OS X-9, ví dụ: \r.

Là một công việc xung quanh, bạn có thể đọc toàn bộ dòng (bằng cách sử dụng một Scanner) và cắt nó, mà sẽ bỏ qua các nhân vật line-breaking (bỏ qua các loại hệ điều hành):

public static void main (String args[]) throws java.io.IOException { 
     String line; 
     Scanner sc = new Scanner(System.in); 
     do { 
      System.out.println("Please a key followed by ENTER:"); 
      line = sc.readLine().trim(); 
     } while (!"q".equals(line)); 
    } 
5

tôi giả những gì được đọc như đầu vào được chứa ENTER bạn bấm phím. Vì bạn đang sử dụng Windows, điều này bao gồm kết thúc dòng CRFL.

Vì vậy, mỗi lần bạn nhập thẻ, bạn thực sự nhập 3 ký tự. Đối với đầu vào đầu tiên của bạn:

  1. một
  2. CR
  3. LF

Hãy thử đọc một dòng đầy đủ thông qua một BufferedReader và chạy một khoảng trắng cắt trên đó, hoặc chỉ đánh giá char đầu tiên của mình.

3

Khi gõ đầu vào trên một dòng lệnh trên một hệ thống Windows, tất cả các dòng được kết thúc trong một nguồn cấp dữ liệu dòng bao gồm các ký tự \r\n. Vì vậy, khi bạn nhập a lần đầu tiên, bạn thực sự đang nhập a\r\n.

Khi mã System.in.read() được chạy, nó chỉ đọc ký tự đầu tiên đã được nhập vào bộ đệm, trong trường hợp này là a. Sau đó vòng lặp chạy, in ra dấu nhắc của bạn và cố gắng đọc ký tự tiếp theo trên bộ đệm. Trong trường hợp này, \r\n vẫn còn trên bộ đệm để nó đọc trong \r. Lặp lại một lần nữa và nó đọc trong \n. Cuối cùng nó in dấu nhắc lần thứ ba kể từ khi bộ đệm trống, nó chờ cho đầu vào của bạn.

Để tránh điều này, tôi khuyên bạn nên sử dụng một phương pháp khác để đọc từ dòng lệnh thay vì System.In. Có lẽ lớp Scanner sẽ phù hợp hơn.

+0

Điều này gần như chính xác, ngoại trừ việc đọc không trả về ký tự; nó trả về byte. Nếu bạn nhập một ký tự không phải ASCII, nó có thể sẽ trả về hai giá trị liên tiếp tùy thuộc vào mã hóa mặc định. –

1

Một điều bạn phải biết là System.in.read() chỉ mất 1 byte đầu vào. Xem tài liệu here.Vì vậy, khi bạn nhập một ký tự a, đã là một byte, bằng cách nhập thêm phím ENTER, ký tự: \r\n, sẽ được chụp thêm read() hai lần nữa.

0

Như @kasoban cho biết họ là một, CR và LF. Nó lặp lại 3 lần, nhưng nó sẽ thay đổi theo hệ điều hành. Vì vậy, tôi khuyên bạn nên sử dụng một máy quét. Bạn có thể tìm thấy mẫu bên dưới

public class DW { 
    public static void main (String args[]) throws java.io.IOException { 
     String s; 
     Scanner scanner = new Scanner(System.in); 
     do { 
      System.out.println("Please a key followed by ENTER:"); 
      s = scanner.nextLine(); 
     } while (!"q".equals(s)); 
     } 
    } 
Các vấn đề liên quan