2016-07-20 19 views
5

Tôi gặp sự cố khi tải chương trình của mình để phản hồi các đầu vào trống. Ví dụ: giả sử tôi muốn nhắc người dùng nhập giá trị bằng tiền với loại BigDecimal cũng như loại tiền tệ. Đây là những gì chương trình trong câu hỏi trông như thế nào.Làm thế nào để có được máy quét Java để xác nhận đầu vào trống?

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

    System.out.print("Enter the amount of money " 
          + "and specify currency (USD or CNY): "); 

    // initialize variable moneyInput 
    BigDecimal moneyInput; 

    // check if moneyInput is numeric 
    try { 
     moneyInput = input.nextBigDecimal(); 
    } catch (InputMismatchException e){ 
     System.err.println("InputMismatchException: non-numeric value"); 
     return; 
    } 

    // specify currency of moneyInput 
    String currencyType = input.next(); 

    ... 
} 

Vì vậy, tại đây, đầu vào như 100.00 USD, hoạt động tốt.

Enter the amount of money and specify currency (USD or CNY): 100.00 USD 
$100.00 USD ≈ ¥670.17 CNY 

Đầu vào như ASDF USD kết quả phù hợp trong thông báo lỗi.

Enter the amount of money and specify currency (USD or CNY): ASDF USD 
InputMismatchException: non-numeric value 

Nhưng, làm cách nào để chương trình phản hồi các đầu vào trống, hoặc nhấn ngay phím quay lại hoặc nhập một loạt dấu cách vào dòng đầu tiên? Ví dụ:

Enter the amount of money and specify currency (USD or CNY): 





1000.00 USD 
$1000.00 USD ≈ ¥6701.70 CNY 

Trong ví dụ trên, người dùng chỉ có thể nhấn phím return vô thời hạn cho đến khi có thể đọc được (hợp lệ hoặc không hợp lệ). Tôi muốn thực hiện một số cách để kiểm tra xem người dùng đã nhấn phím quay lại mà không nhập bất kỳ điều gì có ý nghĩa.

Một kết quả khác mà tôi không biết cách giải thích là nếu người dùng nhập CHỈ giá trị tiền tệ, sau đó nhấn [return] một loạt lần trước khi cuối cùng nhập tiền tệ.

Ví dụ:

Enter the amount of money and specify currency (USD or CNY): 100.00 



USD 
$100.00 USD ≈ ¥670.17 CNY 

Làm thế nào để có được chương trình để nhắc nhở người dùng với một cái gì đó giống như Please specify the currency: sau khi một giá trị số là đầu vào và ép người dùng [trở lại]? Một cái gì đó như

Enter the amount of money and specify currency (USD or CNY): 100.00 
Please specify the currency: USD 
$100.00 USD ≈ ¥670.17 CNY 

tôi đã có thể để đạt được các chức năng trên bằng cách thay đổi các phần sau khối try-catch để:

input.nextLine(); 
System.out.print("Please specify the currency: "); 
String currencyType = input.nextLine(); 

Nhưng sử dụng phương pháp này, chương trình sẽ mất khả năng cho phép người sử dụng để nhập cả moneyInputcurrencyType vào một dòng, như trong ví dụ đầu tiên. (Và một lần nữa, vẫn có vấn đề khi có thể nhấn [return] vô thời hạn cho mỗi nhắc nhở này cho đến khi có thể đọc được thứ gì đó cuối cùng).

Cảm ơn bạn đã đọc và xin lỗi vì bài đăng dài.

Trả lời

10

Scanner cung cấp hai cơ bản - và đôi khi mâu thuẫn nhau - sử dụng trường hợp:

  1. đọc đầu vào bởi tokens, bất chấp bất kỳ khoảng trắng Inbetween (đây là những gì mã ban đầu của bạn không)
  2. đọc đầu vào bởi dòng, mà không xử lý bất kỳ nội dung nào của các dòng đó đặc biệt

Nói chung trộn hai là một ý tưởng tồi (nó hoạt động, nhưng có lẽ không phải cách bạn dự định). Các phương pháp đọc mã thông báo như next()nextBigDecimal() bỏ qua các dòng mới.

Nếu bạn muốn xử lý Nhập bạn cần phải đọc line-by-line đầu vào của người dùng với Scanner.nextLine() và phân tích mỗi dòng riêng (ví dụ: line.split("\\s+")), thay vì sử dụng Scanner 's phương pháp token-đọc.

Một số người thích sử dụng lồng nhau Scanner s và đọc dòng nhập phù hợp với một Scanner sau đó chuyển dòng vào một Scanner mới để mã hóa chỉ dòng đó.

Ví dụ:

try (Scanner in = new Scanner(System.in)) { 
    while (in.hasNextLine()) { 
    try { 
     String line = in.nextLine(); 
     Scanner lineScan = new Scanner(line); 
     BigDecimal moneyInput = lineScan.nextBigDecimal(); 
     String currency = lineScan.next(); 
     // do something 
    } catch (NoSuchElementException | IllegalStateException e) { 
     System.err.print("Please enter the VALUE followed by the CURRENCY"); 
    } 
    } 
} 

Nếu bạn không muốn sử dụng một lồng nhau Scanner có một số cơ chế, xấp xỉ tương đương khác. Dưới đây là các ý chính, nhưng bạn có thể sẽ muốn bổ sung thêm mã lỗi xử lý (ví dụ như nếu new BigDecimal() ném một ngoại lệ:

Sử dụng String.split():

String[] parts = line.split("\\s+"); 
if (parts.length == 2) { 
    BigDecimal moneyInput = new BigDecimal(parts[0]); 
    String currency = parts[1]; 
    // do something 
} else { 
    System.err.println("Please enter the VALUE followed by the CURRENCY"); 
} 

Sử dụng Pattern:

/** 
* Matches one or more digits, optionally followed by a . and more digits, 
* followed by whitespace then one or more uppercase letters. 
*/ 
private static final Pattern MONEY_PATTERN = 
    Pattern.compile("(\\d+(?:\\.\\d+))\\s+([A-Z]+)"); 

Sau đó:

Matcher m = MONEY_PATTERN.matcher(line); 
if (m.matches()) { 
    BigDecimal moneyInput = new BigDecimal(m.group(1)); 
    String currency = m.group(2); 
// do something 
} else { 
    System.err.println("Please enter the VALUE followed by the CURRENCY"); 
} 
+0

Xin chào, bạn có thể vui lòng cho biết cách sử dụng phương thức phân tích cú pháp với 'line.split (" \\ s + ")' để đạt được kết quả tương tự không? Tôi không quen với phương pháp đó nên tôi gặp khó khăn với cú pháp. Cảm ơn –

+1

Đã thêm các ví dụ khác. – dimo414

+0

Ok, làm cách nào tôi có thể kiểm tra riêng xem liệu 'tiền tệ' có hợp lệ không? Tôi muốn nó hoạt động giống như 'moneyInput', tức là nếu một cái gì đó như' 100.00 abc' hoặc '100.00' được nhập vào, người dùng được nhắc nhiều lần cho' currency' chỉ, và một khi họ nhập một loại tiền tệ hợp lệ như ' USD', chương trình tiếp tục bình thường. Tôi đã thử sử dụng vòng lặp do-while khác bên trong để kiểm tra tiền tệ, và điều này làm việc ngoại trừ khi một đầu vào trống được nhập, mà về cơ bản là cùng một vấn đề tôi đã có ở đầu bài đăng này (đây là mã của tôi: http: // pastebin .com/raw/CT0qjBPk và ảnh chụp màn hình chương trình: http://imgur.com/a/mjfaL). –

Các vấn đề liên quan