2015-07-26 7 views
5

Ich schreibe ein Programm, in dem ich Eingaben von der Tastatur nehmen muss. Ich muss eine Nummer eingeben, aber ich bin mir nicht sicher, ob es ein int oder ein double ist. Hier ist der Code, den ich (für diesen spezifischen Teil) haben:Wie lese ich Eingaben, die ein int oder ein double sein könnten?

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

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

Ich weiß, ich kann eine String bekommen und tun parseInt() oder parseDouble(), aber ich weiß nicht, eine, die es sein wird.

+1

In der Tat wäre das Lesen in einem 'String' am besten. Dann müssen Sie überprüfen, ob die angegebene Nummer eine Zahl ist. Wenn es einen Punkt oder ein Komma enthält und der linke und der rechte Teil numerisch sind, ist es ein "Doppel". Andernfalls, wenn kein Punkt oder Komma vorhanden ist, aber der Rest numerisch ist, ist es ein "int".Um zu überprüfen, ob es sich um ein Double handelt, können Sie [regex] (https://en.wikipedia.org/wiki/Regular_expression) verwenden: "-? \\ d + (\\. \\ d +)?", Für Zahlen Sie kann "[0-9] *" verwenden. – pietv8x

+0

@ pietv8x Natürlich würde dieses Regex-Muster nur für eine begrenzte Anzahl von Gebietsschemas funktionieren, die Fließkommazahlen ähnlich der englischen formatieren. Und selbst in einem englischen Gebietsschema können Ganzzahldaten Gruppierungstrennzeichen usw. enthalten, die zu Fehlern führen können. – Hulk

Antwort

2

Verwenden Sie einfach eine double egal was es ist. Es gibt keine bemerkbar Verlust bei der Verwendung eines Doppelgängers für ganzzahlige Werte.

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

Dann, wenn Sie müssen wissen, ob Sie ein Doppel- oder nicht bekommen haben, können Sie es Math.floor mit überprüfen:

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

Verwirren Sie nicht mit catchNumberFormatException ing, nicht suchen sie die Zeichenfolge für einen Zeitraum (die nicht einmal richtig sein könnte, zum Beispiel, wenn der Eingang ist 1e-3 es ein Doppel ist (0.001), aber nicht über eine Periode. Nur analysieren sie als double und bewegen.

Vergessen Sie auch nicht, dass sowohl nextInt() als auch nextDouble()do not capture the newline, so you need to capture it with a nextLine() after using them.

+0

Danke.Der zweite Code-Block mit der int-Anweisung, die Sie mir gegeben haben, war sehr einfach und verständlich, aber sehr hilfreich. – newplayer12132

5

Nun, Ints sind auch verdoppelt, wenn Sie also davon ausgehen, dass alles doppelt ist, werden Sie mit Ihrer Logik in Ordnung sein. Wie folgt:

Es wird nur komplex, wenn Sie die Eingabe aus irgendeinem Grund als Ganzzahl benötigen. Und dann wäre parseInt(), um nach int zu testen, in Ordnung.

+0

Obwohl ich deiner Antwort zustimme, fühle ich, dass dein erster Satz ein bisschen irreführend ist. Sicher kann ein ganzzahliger Wert [normalerweise] in einem doppelten Typ dargestellt werden, aber ich würde nicht sagen, dass ein int ein Doppel ist. Sie haben nicht nur unterschiedliche Speicher-Fußabdrücke (int verwendet 4 Bytes, während Double 8 Bytes verwendet), sondern auch die Art, wie sie den Wert tatsächlich speichern. Dies ist für OP völlig irrelevant und Ihre Antwort würde definitiv für ihn/sie funktionieren, aber ich wollte dies hier nur für zukünftige Leser lassen. Glücklicherweise ist die Umwandlung von double in int schmerzlos, wenn der Wert wirklich eine Ganzzahl ist. – JNYRanger

0

Sie könnten versuchen, die Bodenfunktion zu verwenden, um zu überprüfen, ob es sich um ein Doppel handelt. Wenn Sie nicht wissen, schneidet die Floor-Funktion grundsätzlich alle Dezimalzahlen ab. So können Sie die Anzahl mit und ohne Dezimalzahl vergleichen. Wenn sie gleich sind, kann die Zahl als Ganzzahl behandelt werden, ansonsten als doppelt (vorausgesetzt, Sie müssen sich keine Sorgen über große Zahlen wie Longs machen).

String choice = input.nextLine(); 

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

Oh, ich habe gerade die Methode von der Frage und habe nicht bemerkt, dass es nicht in der String-Klasse war. Fest, danke. @ durron597 – Zarwan

+0

Ich habe meinen Downvote entfernt, aber es ist nicht notwendig, 'parseDouble' zweimal aufzurufen. – durron597

0

Was ich tun würde, ist String Eingang bekommen, und analysieren sie entweder als Doppel- oder eine ganze Zahl ist.

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 

Auf diese Weise können Sie sicherstellen, dass Sie durch ganzzahlige Genauigkeit verlieren nicht nur ein Doppelzimmer (Doppelzimmer haben einen anderen Bereich der möglichen Werte als ganze Zahlen) Parsen, und Sie können die Fälle, in denen weder eine gültige ganze Zahl Griff oder doppelt eingegeben wurde. Wenn der Code im Block try eine Ausnahme auslöst, wird der Code im catch-Block ausgeführt. Wenn in unserem Fall eine Ausnahme durch die Methode parseInt() ausgelöst wird, führen wir den Code im catch-Block aus, in dem sich der zweite try-Block befindet. Wenn eine Ausnahme von der Methode parseDouble() ausgelöst wird, führen wir den Code innerhalb des zweiten catch-Blocks aus, der eine Fehlermeldung ausgibt.

+0

Warum die Downvotes ?! – SamTebbs33

+0

Ich bin nicht der Downvoter, aber: [Integer.parseInt] (http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#parseInt-java.lang.String-) tut viel weniger als [Scanner.nextInt] (http://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#nextInt--) (oder die doppelte Version) in Begriffen Umgang mit Locale- und NumberFormat-Problemen. (das heißt: es tut gar nichts und wirft nur, wenn es auf etwas trifft, das kein numerisches ASCII-Zeichen ist) – Hulk