Java: Wie kann ich bei einer Integer-Scanner-Eingabe whitespaces verbieten?

4 Antworten

So wirklich notwendig ist das nicht, denn auf technischer Ebene wird das Leerzeichen bereits als Trennzeichen gewertet.

Bei diesem Code:

Scanner reader = new Scanner(System.in);
int x = reader.nextInt();

und dieser Eingabe:

12 34

stände in x nur der Wert 12. Würdest du in deinem Programm nun noch eine Anweisung ergänzen:

int y = reader.nextInt();

würde die 34 in y gespeichert werden.

Um aber ganz sicher zu gehen, ob der nächste zu lesende Token einer Ganzzahl entspricht (statt bspw. einem Buchstaben), kannst du mit hasNextInt prüfen.

if (reader.hasNextInt()) {
  int number = reader.nextInt();
  // ...
}

Letzlich fehlt also nur eine Randnotiz für den Nutzer, Zahlen stets ohne Leerzeichen und Dezimalstelle eingeben, damit er z.B. bei Tausenderstellen nicht auf entsprechende Ideen kommt.

Wenn du unbedingt eine Leerzeichenprüfung durchführen möchtest, sollte man auch erwarten, dass du die volle Zeile zu einer Zahl verwertest. Dabei würde ich gleich von Anfang einen regulären Ausdruck angeben, der ausschließlich Zahlen erlaubt (also ebenso Buchstaben und generell Whitespaces ausklammert).

String input = reader.nextLine();

if (input.matches("^\\d+$")) {
  try {
    int number = Integer.parseInt(input);
    // ...
  }
  catch (NumberFormatException ex) {
    // handle error with message or similar ...
  }
}
else {
  // line input is not a number ...
}

PS.: Die Variable Zahl in deinem Code würde ich umbenennen zu zahl, um der üblichen Java-Konvention zu entsprechen (Variablennamen beginnen mit einem Kleinbuchstaben). Statt dem Typ Integer reicht das primitive Pendant int vollkommen aus.

Das testen, ob ein String eine ganze Zahl ist oder nicht würde wie folgt gehen:

String s = scanner.nextLine();
int i;
try {
    i = Integer.parseInt(s);
} catch (NumberFormatException e) {
    System.err.println("Geben Sie eine Ganzzahl ein!");
}

Dein Primzahl-Tester allerdings funktioniert nicht, den solltest Du dir noch mal anschauen - und wenn er dann funktioniert, könntest Du Dir überlegen, ob Du wirklich immer beim Teiler 2 anfangen musst zu testen (Spoiler: Nein - Es reicht immer bei der Wurzel der Zahl + 1 anzufangen!).

Viel Spaß dabei und bei Rückfragen gerne entweder googlen oder kommentieren.

Woher ich das weiß:Hobby
ThePr013 
Fragesteller
 01.12.2021, 15:39
ich habe mal diese variente probiert, leider gibt es konflikte zwischen den datentypen bei der eigentlichen berechnung, da ich ja, um auf whitespaces zu prüfen meine eingabe-variable zu string umändern muss. ich vermute, dass ich einfach logische fehler im code habe.  was kann ich anders machen?

  import java.util.Scanner;



public class 

Primzahl {
        public static void main(String[] args) {
                Scanner scanner = new Scanner(System.in);
                boolean isPrime = true;
                int temp;


                System.out.println("Gib ne Zahl");
                String zahl = scanner.nextLine();

                try {
                        temp = Integer.parseInt(zahl);
                } catch (NumberFormatException e) {
                        System.err.println("Geben Sie eine Ganzzahl ein!");
                }

                for (int i=2; i<zahl; i++)
                {
                        temp=zahl%i;
                        if (temp==0)
                        {
                                isPrime=false;
                                break;
                        }
                }
                if(isPrime)
                        System.out.println(zahl + " is a Prime Number");
                else
                        System.out.println(zahl + " is not a Prime Number");
        }
}
0

Wenn es um den Lerneffekt geht, zu gucken, ob die Eingabe ein Leerzeichen enthält, kannst du mit String.contains() arbeiten. Zum Beispiel so:

String tmp = scanner.nextLine();
int Zahl = -1;
if (tmp.contains(" ")) {
	System.out.println("Nur natürliche Zahlen sind erlaubt!");
} else {
	try {
		Zahl = Integer.parseInt(tmp);
	} catch (Exception e) {
		System.out.println("Eingabe war keine natürliche Zahl!");
	}
}

Ansonsten reichen try und catch. Wenn der Versuch zur Umwandlung in ein Integer schief läuft, hast du alle potenziellen Fälle abgefangen, die einem Nutzer einfallen könnten dort einzutippen. Also alles, was kein Integer ist, wird damit abgefangen. Daher würde ausreichen:

String tmp = scanner.nextLine();
int Zahl = -1;
try {
	Zahl = Integer.parseInt(tmp);
} catch (Exception e) {
	System.out.println("Eingabe war keine natürliche Zahl!");
}
ThePr013 
Fragesteller
 01.12.2021, 15:41

ich habe mal die 2. variente probiert, aber leider gibt es konflikte zwischen den datentypen bei der eigentlichen berechnung, da ich ja, um auf whitespaces zu prüfen meine eingabe-variable zu string umändern muss. ich vermute, dass ich einfach logische fehler im code habe. was kann ich anders machen?

0
ThePr013 
Fragesteller
 01.12.2021, 15:41
import java.util.Scanner;

public class Primzahl {
        public static void main(String[] args) {
                Scanner scanner = new Scanner(System.in);
                boolean isPrime = true;
                int temp;


                System.out.println("Gib ne Zahl");
                String zahl = scanner.nextLine();

                try {
                        temp = Integer.parseInt(zahl);
                } catch (NumberFormatException e) {
                        System.err.println("Geben Sie eine Ganzzahl ein!");
                }

                for (int i=2; i<zahl; i++)
                {
                        temp=zahl%i;
                        if (temp==0)
                        {
                                isPrime=false;
                                break;
                        }
                }
                if(isPrime)
                        System.out.println(zahl + " is a Prime Number");
                else
                        System.out.println(zahl + " is not a Prime Number");
        }
}
0
GuteAntwort2021  01.12.2021, 16:00
@ThePr013

Wenn ich dein Codesnippet übernehme, dann müsstest du es wie folgt abändern:

import java.util.Scanner;


public class Primzahl {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        boolean isPrime = true;
        int temp=-1;


        System.out.println("Geben Sie eine Ganzzahl ein!");
        String zahl = scanner.nextLine();
        try {
            temp = Integer.parseInt(zahl);
        } catch (NumberFormatException e) {
            System.err.println("Das war keine Ganzzahl!");
        }
        for (int i=2; i<Math.floor((temp/2)+0.5); i++) {
            if (temp%i==0) {
                isPrime=false;
                break;
            }
        }
        if(isPrime)
            System.out.println(zahl + " is a Prime Number");
        else
            System.out.println(zahl + " is not a Prime Number");
    }
}

Zunächst einmal hast du zahl als String und temp als Integer gewählt, dann aber im Schleifenkopf den String (Zahl) als Vergleichsbasis gewählt. Das funktioniert natürlich nicht.

Wenn du das behoben hättest, würde es immer noch nicht funktionieren, denn du schreibst:

temp=zahl%i;

Womit du aber die eigentliche Zahl überschreiben würdest. Zumal du hierbei int = String modulo int schreibst... Gäbe also auch einen Datentyp-Konflikt.

Darüber hinaus habe ich deine Schleifendurchläufe halbiert, denn wenn i > als die Hälfte der Zahl ist, wird der Teiler kleiner 2 sein. Ist also unnötig. Im Grunde könnte man die Anzahl der Berechnungen noch wesentlich weiter abkürzen (auch ohne Faktorisierung), denn alle zweistelligen Primzahlen müssen auf 1,3,7 oder 9 enden. Damit entfallen 60% aller Durchläufe, womit wir schon nur noch 30% der Zahlen testen müssten.

Das ließe sich dann auch noch weiter abkürzen, denn wenn du zum Beispiel auf 2 und 3 getestet hast, hättest du auch alle Zahlen größer >= 1/3 der Zahl getestet. Bei einer Zahl wie 1017 mag das keine Rolle spielen, bei einer Zahl wie 2222222229 hingegen schon.

0
ThePr013 
Fragesteller
 01.12.2021, 16:26
@GuteAntwort2021

Ich danke dir vielmals für die ausführliche antwort! absolut hilfreich für mich als einen anfänger

1

Du kannst doch mit Replace() einfach die "Whitespaces" entfernen ... !? o_O

Woher ich das weiß:Hobby – Programmierer, EDV, ... seit den 80er :)