Exceptions - Ausnahmebehandlung

  • Themenstarter Themenstarter DanTheMan12
  • Beginndatum Beginndatum
D

DanTheMan12

Gast
Hallo miteinander,
ich habe folgende Aufgabenstellung und hänge eigentlich nur noch an Kleinigkeiten fest. Das heißt, das Programm läuft zumindest schonmal, aber erfüllt noch nicht 100%ig die geforderten Eigenschaften. Vielleicht findet sich jemand, der mir bei den fettgedruckten Sätzen helfen kann.

Ein oft benutztes Verfahren zum Erstellen von Passwörtern ist die Verwendung von Merksätzen oder Zitaten. Von einem einfach zu merkenden Satz werden aus den einzelnen Wörtern jeweils die Buchstaben an einer bestimmten Position herausgenommen und hintereinander gefügt. Ein Passwort sollte aber immer mindestens 6 und maximal 10 Zeichen lang sein.

Implementieren Sie eine Klasse Passwort, die eine statische Methode static String erstellePasswort(String satz, int pos) bereitstellt. Die Methode soll aus einem zu übergebenen Satz und der Angabe der Position unter Verwendung des oben beschriebenen Verfahrens ein Passwort konstruieren. Falls dabei ein Wort kürzer als die gewünschte Position ist, soll statt des Buchstabens ein '?' in das Passwort eingefügt werden. Bei einer unerlaubten Passwortlänge (Anzahl der Wörter im Satz < 6 oder Anzahl der Wörter > 10) soll eine Instanz der selbst zu definierenden Ausnahmeklasse PasswortException ausgeworfen und an die aufrufende Stelle weitergereicht werden. Testen Sie die Methode erstellePasswort in der main-Methode. Verwenden Sie zum Einlesen eines Satzes die Methode nextLine() der Klasse Scanner. In der main-Methode soll die Ausnahmebehandlung durchgeführt werden, die aufgrund fehlerhafter Nutzung der Methode erstellePasswort auftreten kann. Nach der Ausnahmebehandlung soll der Nutzer zur wiederholten Eingabe eines Merksatzes aufgefordert werden.

Für die Lösung der Aufgabe sind die folgenden Methoden der Klasse String zu verwenden.
Java:
// int length() - die Methode ermittelt die Länge eines StringObjektes
String s = "JAVA-IST-TOLL";
int i = s.length();      // i hat den Wert 13

// String[] split(String separator) - zerlegt ein StringObjekt an dem Zeichen separator in ein Array von Teilstrings
String[] woerter = s.split("-");
int len = woerter.length;      //len hat den Wert 3 mit den Teilstrings JAVA, IST, TOLL

// char charAt(int index) - gibt das Zeichen an Position index eines StringObjektes zurück
char c = s.charAt(7);      // c hat den Wert 'T'


Java:
import java.util.Scanner;
	
class PasswortException extends Exception {							// eigene Fehlerklasse
	PasswortException() {
		super();
	}
	PasswortException(String message) {
		super(message);
		System.out.println("Geben Sie erneut einen Satz ein!");		// Aufforderung zur erneuten Eingabe
	}	
} // PasswortException (Klasse)
	
public class Passwort {
	
	public static void main (String[] arg) {
		boolean schleife;																// bool'scher Typ schleife für do-while
		do {
			try {
				Scanner in = new Scanner(System.in);
				String eingabe = in.nextLine();											// Einlesen des Satzes
				int index = 2;															// vordefinierte Position, an der das Zeichen gelesen werden soll
				System.out.println("Passwort: " + erstellePasswort(eingabe, index));	// Aufruf der Methode erstellePasswort
				break;
			} //try
			// wird aufgerufen, wenn die geforderte Position (index) hoeher als die Anzahl der Zeichen des Wortes sind
			catch (StringIndexOutOfBoundsException b) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(b.getMessage());
				schleife = true;
			}
			// wird aufgerufen, wenn der einzulesende Satz <6 oder >10 Woerter hat
			catch (PasswortException c) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(c.getMessage());
				schleife = true;
			}
		} while (schleife = true);
	} // main (Methode)
	
	static String erstellePasswort (String satz, int pos) throws PasswortException {
		int zeichen = satz.length();															// zaehlt Zeichen (inklusive Leerzeichen)
		String[] wort = satz.split(" ");														// splittet den Satz in Woerter durch die Erkennung von " " (Leerzeichen)
		int anzahl = wort.length;																// zaehlt die Woerter
		if (anzahl < 6 || anzahl > 10) throw new PasswortException ("Der Satz muss zwischen 6 und 10 Woerter haben.");
		String password = "";
		for (int i = 0; i < wort.length; i++) {													// Erstellung des Passworts per for-Schleife, durchlaeuft die Woerter
			char a = wort[i].charAt(pos);														// setzt a auf Zeichen an pos-Stelle (2) des i-ten Wortes
			if (wort.length < pos) { 				// bei index = 2 --> StringIndexOutOfBoundsException --> hier bin ich mir nicht sicher, wie es richtig geht
				a = '?';							// ich wuerde gern a auf "?" setzen, aber es wird erst die Ausnahme erkannt, sodass er nichts weiter macht
			}
			password = password + a;															// fuegt dem vorerst erzeugten password a zu und haengt pro Durchlauf das aktuelle a an
		}
		return password;
	} // erstellePasswort (Methode)
	
} // Passwort (Klasse)

Mein Beispielsatz lautet: Ich trinke im Winter gern Tee und meine Position zur Erstellung des Passwortes ist die 2 (also die 3.).

1. Beim zweiten Satz: Ich schreibe in Zeile 9 die Aufforderung, aber wenn ich das Programm ausführe, erscheint erst die Aufforderung und es folgt "Ausnahme wird behandelt", "Der Satz muss zwischen 6 und 10 Woerter haben." aus Zeile 33 bzw. 44. Wie bekomme ich das ganze andersherum?

2. Der erste Satz erfordert ein '?', wenn ein Wort kürzer als die gewünschte Position des Zeichens eines Wortes ist. Wie kann ich das Programm erkennen lassen, dass die Ausnahme stattfindet und das Programm dort, anstelle einer erneuten Eingabeaufforderung, ein '?' für a setzt und die Schleifen weiter durchläuft? Demnach müsste für meinen Beispielsatz das Passwort hi?nre entstehen, da "im" nur 2 Stellen besitzt und somit Position 2 nicht erkannt werden kann.

Vielen Dank im Voraus
 
ist das echt dein Ernst, dass du nicht weißt wie man
Java:
anzahl < 6 || anzahl > 10
"umdreht"?

Analytisches Denken lässt grüßen

Versuch es mal mit
Java:
anzahl >= x && anzahl <= y
 
Ich fürchte du hast mich falsch verstanden bzw. ich habe mich umständlich ausgedrückt.

Java liefert mit dem gegebenen Quellcode folgende Zeilen in der Eingabeaufforderung, wenn ich einen Satz eingebe:
Code:
Ich trinke Tee
Geben Sie erneut einen Satz ein!
Ausnahme wird behandelt:
Der Satz muss zwischen 6 und 10 Woertern haben.

Mein Anliegen ist es, die Aufforderung um 2 Zeilen nach unten zu verschieben (hinter die Ausnahmebehandelung).
 
Ok - das funktioniert jetzt schonmal.

Jetzt bleibt mir das Problem mit dem Fragezeichen. Prinzipiell ist die Fehlerbehandlung für StringIndexOutOfBoundsException ja notwendig, denke ich, oder? Hier müsste ich irgendwie einbauen, dass er für das a ein '?' setzt und die Schleifen weiter durchläuft.
 
Hat keiner eine Idee? Mir fällt absolut nichts ein - hab bishre schon einiges ausprobiert, aber das haut alles nicht hin.
Mein letztes Problem ist:
Falls dabei ein Wort kürzer als die gewünschte Position ist, soll statt des Buchstabens ein '?' in das Passwort eingefügt werden.
 
Wieso solltest du einen Fehler abfangen, wenn du stattdessen einfach nur vorher die Länge prüfen musst. Ich finde, wenn man einen Fehler ohne Probleme vermeiden kann, sollte man das auch tun. Und die Aufgabenstellung sagt auch nicht, dass du dafür einen Fehler werfen oder abfangen musst.
 
Das problem war das die Exception von Java allein geworfen wurde und ich da noch gar nichts gemacht hatte - dann habe ich darauf reagiert und dafür einen catch-Block angefertigt, damit das Programm nicht abbricht.
Das Programm wirft den Fehler, wenn ich auf einen index zugreife, der größer als die Anzahl der Zeichen eines Wortes ist. Daher weiß ich nicht, wo ich die Bedingung einbauen muss, die prüft, ob "wort.length < pos" (Zeile 48).

Aber ich werde mal probieren, ob ich etwas in der Art hinbekomme. Vielen dank schon mal für den Tipp 😉
 
Java schmeisst nicht einfach so eine IndexOutOfBoundsException. Da ist eindeutig ein Programmierfehler, ergo hattest du doch schon was gemacht.
 
also ich kann keinen Fehler finden 🙁
Mein aktueller Quellcode sieht folgendermaßen aus. Kann mir jemand ein genaueren Hinweis geben, ich komm einfach nicht weiter.

Java:
import java.util.Scanner;
	
class PasswortException extends Exception {							// eigene Fehlerklasse
	PasswortException() {
		super();
	}
	PasswortException(String message) {
		super(message + "\n\rGeben Sie erneut einen Satz ein!");	// Aufforderung zur erneuten Eingabe
	}
} // PasswortException (Klasse)
	
public class Passwort {
	
	public static void main (String[] arg) {
		Scanner in = new Scanner(System.in);
		boolean schleife;																// bool'scher Typ schleife für do-while
		int index = 2;																	// vordefinierte Position, an der das Zeichen gelesen werden soll
		do {
			try {
				String eingabe = in.nextLine();											// Einlesen des Satzes
				System.out.println("Passwort: " + erstellePasswort(eingabe, index));	// Aufruf der Methode erstellePasswort
				break;
			} //try
			// wird aufgerufen, wenn die geforderte Position (index) hoeher als die Anzahl der Zeichen des Wortes sind
			catch (StringIndexOutOfBoundsException b) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(b.getMessage());
				System.out.println("Geben Sie erneut einen Satz ein!");					// Aufforderung zur erneuten Eingabe
				schleife = true;
			}
			// wird aufgerufen, wenn der einzulesende Satz <6 oder >10 Woerter hat
			catch (PasswortException c) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(c.getMessage());
				schleife = true;
			}
		} while (schleife = true);
	} // main (Methode)
	
	static String erstellePasswort (String satz, int pos) throws PasswortException {
		int zeichen = satz.length();															// zaehlt Zeichen (inklusive Leerzeichen)
		String[] wort = satz.split(" ");														// splittet den Satz in Woerter durch die Erkennung von " " (Leerzeichen)
		int anzahl = wort.length;																// zaehlt die Woerter
		if (anzahl < 6 || anzahl > 10) throw new PasswortException ("Der Satz muss zwischen 6 und 10 Woerter haben.");
		String password = "";
		for (int i = 0; i < wort.length; i++) {													// Erstellung des Passworts per for-Schleife, durchlaeuft die Woerter
			String aktuellesWort = wort[i];
			int zeichenWort = aktuellesWort.length();
			char a = wort[i].charAt(pos);														// setzt a auf Zeichen an pos-Stelle (2) des i-ten Wortes
			if (zeichenWort < pos) {
				a = '?';
			}
			password = password + a;															// fuegt dem vorerst erzeugten password a zu und haengt pro Durchlauf das aktuelle a an													
		}
		return password;	} // erstellePasswort (Methode)
	
} // Passwort (Klasse)

In den Zeilen 50 bis 52 (siehe unten) soll eigentlich die Prüfung stattfinden, aber es kommt gar nicht dazu, da vorher abgebrochen wird und eine Exception-Meldung kommt.

Java:
			if (zeichenWort < pos) {
				a = '?';
			}

Eine andere Idee habe ich hiermit versucht umnzusetzen, aber die bringt mich auch nicht weiter. Ich hab hier einfach nochmal das Zählen der Zeichen zerpflückt.

Java:
			String aktuellesWort = wort[i];
			int zeichenWort = aktuellesWort.length();
			if (zeichenWort < pos) {
				a = '?';
			}
 
Du versuchst ERST den Buchstaben zu holen und dann schaust du ob die Länge des Wortes überhaupt reicht.

Java:
char a = wort[i].charAt(pos);
if (zeichenWort < pos) {
    a = '?';
}

Da er aber auf der ersten Zeile eventuell schon eine Exception wirft kommt er an der Längenüberprüfng nicht mehr vorbei. Z.B. bei "in" gibt es keine Position 2, da auch hier der Index 0-based angegeben werden muss.

Also entweder um das charAt einen Try/Catch legen (was an dieser Stelle natürlich extrem unschön wäre) oder:
Java:
char a;
if (zeichenWort < pos) {
    a = '?';
} else {
    a = wort[i].charAt(pos);
}

PS: Ich würde englische Bezeichner nutzen. Dieses Denglisch sieht ziemlich lala aus. Ich sage nur Pfanne.getPfannekuchen().toString().halbiere();
 
hmm
solche Sachen habe ich schon in diversen Formen versucht, aber es kommt immer das gleiche dabei heraus:

Bsp.: "Ich trinke im Winter gern Tee" (hier wäre im zu kruz und müsste durch ein '?' ersetzt werden.
Code:
Ich trinke im Winter gern Tee
Ausnahme wird behandelt:
String index out of range: 2
Geben Sie erneut einen Satz ein!

Das bekomme ich auch mit dem zuletzt vorgeschlagenen Konstrukt zu lesen. 🙁
 
Das wundert mich ja auch - ich kann das ja vollkommen nachvollziehen, dass es so gemacht werden müsste, aber ich bekomme immer eine Exception-Meldung.
Hier ist nochmal mein aktueller Code mit dem Part von Noctarius. Wen es funktionieren würde, bräuchte ich ja theoretisch gar keinen catch-Block für StringIndex, aber dadurch, dass es noch nicht klappt, würde das Programm imemr abbrechen. Ich scheine blind zu sein :/

Java:
import java.util.Scanner;
	
class PasswortException extends Exception {							// eigene Fehlerklasse
	PasswortException() {
		super();
	}
	PasswortException(String message) {
		super(message + "\n\rGeben Sie erneut einen Satz ein!");	// Aufforderung zur erneuten Eingabe
	}
} // PasswortException (Klasse)
	
public class Passwort {
	
	public static void main (String[] arg) {
		Scanner in = new Scanner(System.in);
		boolean schleife;																// bool'scher Typ schleife für do-while
		int index = 2;																	// vordefinierte Position, an der das Zeichen gelesen werden soll
		do {
			try {
				String eingabe = in.nextLine();											// Einlesen des Satzes
				System.out.println("Passwort: " + erstellePasswort(eingabe, index));	// Aufruf der Methode erstellePasswort
				break;
			} //try
			// wird aufgerufen, wenn die geforderte Position (index) hoeher als die Anzahl der Zeichen des Wortes sind
			catch (StringIndexOutOfBoundsException b) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(b.getMessage());
				System.out.println("Geben Sie erneut einen Satz ein!");					// Aufforderung zur erneuten Eingabe
				schleife = true;
			}
			// wird aufgerufen, wenn der einzulesende Satz <6 oder >10 Woerter hat
			catch (PasswortException c) {
				System.out.println("Ausnahme wird behandelt:");
				System.out.println(c.getMessage());
				schleife = true;
			}
		} while (schleife = true);
	} // main (Methode)
	
	static String erstellePasswort (String satz, int pos) throws PasswortException {
		int zeichen = satz.length();															// zaehlt Zeichen (inklusive Leerzeichen)
		String[] wort = satz.split(" ");														// splittet den Satz in Woerter durch die Erkennung von " " (Leerzeichen)
		int anzahl = wort.length;																// zaehlt die Woerter
		if (anzahl < 6 || anzahl > 10) throw new PasswortException ("Der Satz muss zwischen 6 und 10 Woerter haben.");
		String password = "";
		for (int i = 0; i < wort.length; i++) {													// Erstellung des Passworts per for-Schleife, durchlaeuft die Woerter
			String aktuellesWort = wort[i];
			int zeichenWort = aktuellesWort.length();
			char a;
			if (zeichenWort < pos) {
				a = '?';
			} else {
				a = wort[i].charAt(pos);
			} 
			password = password + a;															// fuegt dem vorerst erzeugten password a zu und haengt pro Durchlauf das aktuelle a an
		}
		return password;
	} // erstellePasswort (Methode)
	
} // Passwort (Klasse)
 
Ja, da passiert nichts anderes. Das einzige, was nun neu ist, dass wenn man einen richtigen Satz eingibt (bei dem alle Wörter mindestens 3 Zeichen haben), kommen nur Fragezeichen.

z.B.: "Ich trinke auf dem Dach gern Tee" liefert '???????'
 
Ich habs 😀
omg...

ich habe durch Zufall gerade folgenden Satz probiert:
"Drei plus 5 macht nicht Neun"
und das Ergebnis war 'eu?ccu'

Da ist mir aufgefallen, dass die Exception-Meldung genau dann autritt, wenn ein Wort genau so lang ist wie "pos" (also 2)

Nun habe ich:

Java:
			char a;
			if (zeichenWort <= pos) {
				a = '?';
			} else {
				a = wort[i].charAt(pos);
			}

Also ein
Code:
<=
und damit funktioniert es 😀
Bsp.: "Ich trinke im Winter gern Tee" ergibt nun hi?nre.
Vielen dank für eure Mühen und die Nerven, die ihr mitgebracht hat. Ich hab ja gesagt ich bin blind :/
DANKE
 
Ich will dich ja nicht beunruhigen, aber ich sitze gerade noch an der gleichen Aufgabe und laut Aufgabenstellung ist der Index nicht fest, sondern wird auch vom Benutzer eingegeben:

Die Methode soll aus einem zu übergebenen Satz und der Angabe der Position unter Verwendung des oben beschriebenen Verfahrens ein Passwort konstruieren.

Nicht das du deshalb Punktabzug bekommst...
:toll:
 
Da hast du Recht... habe schon abgeschickt ^^ naja sollte eigentlich schnell gemacht sein dieser Zusatz - dann muss ich heute erstmalig zweimal schicken
Danke für den Tipp
 

Neue Themen


Zurück
Oben