2015-07-26 14 views
5

Tôi đang viết một chương trình mà tôi cần lấy đầu vào từ bàn phím. Tôi cần phải nhập số, nhưng tôi không chắc đó có phải là số int hoặc double hay không. Dưới đây là đoạn code mà tôi có (cho một phần cụ thể):Làm cách nào để đọc đầu vào có thể là int hoặc gấp đôi?

import java.io.*; 
import java.util.*; 

//... 
Scanner input = new Scanner(System.in); 
int choice = input.nextInt(); 

Tôi biết tôi có thể nhận được một String và làm parseInt() hoặc parseDouble(), nhưng tôi không biết cái nào nó sẽ được.

+1

Thật vậy, việc đọc trong một 'Chuỗi' sẽ là tốt nhất. Sau đó, bạn sẽ cần xác minh rằng số đã cho là một số. Nếu nó chứa một dấu chấm, hoặc dấu phẩy và phần bên trái và bên phải là số, thì nó là một 'double'. Khác nếu không có dấu chấm hoặc dấu phẩy nhưng phần còn lại là số, nó là 'int'.Để kiểm tra nếu nó là một đôi bạn có thể sử dụng [regex] (https://en.wikipedia.org/wiki/Regular_expression): "-? \\ d + (\\. \\ d +)?", Cho số bạn có thể sử dụng "[0-9] *". – pietv8x

+0

@ pietv8x Tất nhiên, mẫu regex này sẽ chỉ hoạt động đáng tin cậy cho một số lượng giới hạn các ngôn ngữ định dạng các số dấu phẩy động tương tự như số tiếng Anh. Và ngay cả trong một miền địa phương tiếng Anh, dữ liệu số nguyên có thể chứa nhóm phân cách vv có thể dẫn đến lỗi. – Hulk

Trả lời

2

Chỉ cần sử dụng double cho dù đó là gì. Không có tổn thất đáng chú ý khi sử dụng giá trị kép cho các giá trị tích phân.

Scanner input = new Scanner(System.in); 
double choice = input.nextDouble(); 

Sau đó, nếu bạn cần phải biết liệu bạn đã nhận được một đôi hay không, bạn có thể kiểm tra nó bằng cách sử Math.floor:

if (choice == Math.floor(choice)) { 
    int choiceInt = (int) choice); 
    // treat it as an int 
} 

Đừng gây rối với catch ing NumberFormatException, không tìm kiếm chuỗi trong một khoảng thời gian (có thể thậm chí không chính xác, ví dụ nếu đầu vào là 1e-3 thì nó là một đôi (0.001) nhưng không có một khoảng thời gian, chỉ cần phân tích cú pháp đó là double và di chuyển trên.Ngoài ra, đừng quên rằng cả hai số nextInt()nextDouble()do not capture the newline, so you need to capture it with a nextLine() after using them.

+0

Thanks.The khối thứ hai của mã với tuyên bố int bạn đã cho tôi rất đơn giản và dễ hiểu, nhưng rất hữu ích. – newplayer12132

5

Vâng, ints cũng tăng gấp đôi vì vậy nếu bạn cho rằng mọi thứ đều là gấp đôi, bạn sẽ ổn với logic của mình. Như thế này:

import java.io.*; 
import java.util.*; 
Scanner input = new Scanner(System.in); 
double choice = input.nextDouble(); 

Nó chỉ phức tạp nếu bạn cần đầu vào là số nguyên vì lý do gì. Và sau đó, parseInt() để kiểm tra cho int sẽ là tốt.

+0

Mặc dù tôi đồng ý với câu trả lời của bạn, tôi cảm thấy câu đầu tiên của bạn hơi gây hiểu nhầm. Chắc chắn một giá trị số nguyên có thể [thường] được thể hiện trong một kiểu kép, nhưng tôi sẽ không nói rằng một int là một đôi. Không chỉ chúng có dấu chân bộ nhớ khác nhau (int sử dụng 4 byte, trong khi đôi sử dụng 8 byte) cách mà chúng thực sự lưu trữ giá trị là một chút khác nhau. Điều này hoàn toàn không liên quan đến OP và câu trả lời của bạn chắc chắn sẽ làm việc cho anh ta/cô ấy, nhưng tôi chỉ muốn để điều này ở đây cho độc giả tương lai. May mắn là đúc từ đôi đến int thì không đau nếu giá trị thực sự là một số nguyên. – JNYRanger

0

Bạn có thể thử sử dụng chức năng sàn để kiểm tra xem nó có phải là gấp đôi hay không. Trong trường hợp bạn không biết, chức năng sàn cơ bản cắt giảm bất kỳ số thập phân. Vì vậy, bạn có thể so sánh số có và không có số thập phân. Nếu chúng giống nhau, thì số đó có thể được coi là số nguyên, nếu không thì sẽ là số nguyên (giả sử bạn không cần lo lắng về số lượng lớn như số điện thoại dài).

String choice = input.nextLine(); 

if (Double.parseDouble(choice) == Math.floor(Double.parseDouble(choice)) { 
    //choice is an int 
} else { 
    //choice is a double 
} 
+0

Ồ, tôi vừa nhận được phương thức từ câu hỏi và không nhận ra nó không nằm trong lớp String. Cố định, cảm ơn. @ durron597 – Zarwan

+0

Tôi đã xóa bỏ phiếu giảm giá của mình, nhưng không cần thiết phải gọi 'parseDouble' hai lần. – durron597

0

gì tôi sẽ làm là có được String đầu vào, và phân tích nó như hoặc là một đôi hoặc một số nguyên.

String str = input.next(); 
int i = 0; 
double d = 0d; 
boolean isInt = false, isDouble = false; 

try { 
    // If the below method call doesn't throw an exception, we know that it's a valid integer 
    i = Integer.parseInt(str); 
    isInt = true 
}catch(NumberFormatException e){ 
    try { 
     // It wasn't in the right format for an integer, so let's try parsing it as a double 
     d = Double.parseDouble(str); 
     isDouble = true; 
    }catch(NumberFormatException e){ 
     // An error was thrown when parsing it as a double, so it's neither an int or double 
     System.out.println(str + " is neither an int or a double"); 
    } 
} 

// isInt and isDouble now store whether or not the input was an int or a double 
// Both will be false if it wasn't a valid int or double 

Bằng cách này, bạn có thể đảm bảo rằng bạn không bị mất số nguyên chính xác bằng cách chỉ phân tích một đôi (đôi có một phạm vi khác nhau của giá trị có thể so với các số nguyên), và bạn có thể xử lý các trường hợp không phải là một số nguyên hợp lệ hoặc đôi đã được nhập.

Nếu ngoại lệ được ném bởi mã bên trong khối try, mã trong khối catch được thực thi. Trong trường hợp của chúng tôi, nếu một ngoại lệ được ném bởi phương pháp parseInt(), chúng tôi thực thi mã trong khối catch, nơi khối thử thứ hai là. Nếu một os ngoại lệ được ném bởi phương thức parseDouble(), thì chúng ta thực thi mã bên trong khối catch thứ hai, nó sẽ in ra một thông báo lỗi.

+0

Tại sao các downvotes ?! – SamTebbs33

+0

Tôi không phải người downvoter, nhưng: [Integer.parseInt] (http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-) ít hơn nhiều so với [Scanner.nextInt] (http://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#nextInt--) (hoặc phiên bản kép) về mặt xử lý các vấn đề Locale- và NumberFormat-. (ví dụ: nó không có gì cả và chỉ ném nếu nó gặp bất cứ điều gì không phải là một số ASCII char) – Hulk

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