Übungen zu „Objektorientierte Programmierung in Java“ PD Dr. Wolfgang Goerigk Sommersemester 2009 Musterlösungen Serie 2 Aufgabe 2.1 (Laboraufgabe, Eingabe von der Standardeingabe) Ändern Sie das Programm „Mehrwertsteuer“ aus Aufgabe 1.2 (Serie 1) so, dass es seine Eingabe von der Standardeingabe (System.in, also i.a. der Konsole) liest. Nutzen Sie dazu einen DataInputStream und die entsprechenden Methoden readDouble() und readInt() dieser Klasse. Hinweise: In der Java-API-Dokumentation finden Sie den Konstruktor, der den InputStream System.in als Argument nimmt und einen DataInputStream erzeugt. Die Klassen, die Sie in dieser und der folgenden Aufgabe benötigen, finden sich im Package "java.io", das Sie durch ein "import java.io.*" am Anfang Ihrer Programmdatei importieren müssen, um die Identifikatoren dieses Package ohne PackageQualifizierer benutzen zu können. Lösung: package Serie_2; import java.util.Scanner; public class Aufgabe_2_1 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Nettobetrag (Beispiel 123,45): "); double netto = scanner.nextDouble(); System.out.println("Mehrwertsteuersatz (Beispiel 19): "); int mwst = scanner.nextInt(); System.out.println("Bruttobetrag = " + (netto + netto * mwst / 100.0)); } } Man beachte, dass die Utility-Klasse java.util.Scanner (ab Java 1.5.0) Gleitkommazahlen im lokalisierten (i.a. deutschen) Zahlenformat einliest, d.h. in der Form 1000,75 (mit Komma statt Punkt). Das Eingabemedium ist nun die Standard-Eingabe (Input-Stream System.in). Aufgabe 2.2 (Laboraufgabe, Eingabe aus einer Datei) Ändern Sie Ihr Programm aus Aufgabe 2.1 so, dass es den Nettobetrag (double) und den Mehrwertsteuersatz (int) aus einer Textdatei liest, in der diese Daten in der ersten Zeile hintereinander stehen. Suchen Sie dazu im Package "java.io" eine entsprechende Klasse, die die Eingabe aus Dateien (engl. files) ermöglicht. Ein Muster für die Textdatei finden Sie auf der Vorlesungs-Webseite. Lösung: package Serie_2; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Aufgabe_2_2 { public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(new File("Mehrwertsteuer.txt")); double netto; int mwst; System.out.println(netto = scanner.nextDouble()); System.out.println(mwst = scanner.nextInt()); System.out.println("Bruttobetrag = " + (netto + netto * mwst / 100.0) + " €"); } } Man beachte, dass die Utility-Klasse java.util.Scanner (ab Java 1.5.0) Gleitkommazahlen im lokalisierten (i.a. deutschen) Zahlenformat einliest, d.h. in der Form 1000,75 (mit Komma statt Punkt). Das Eingabemedium ist nun die Datei (Input-Stream new File("Mehrwertsteuer.txt")). Da Datei-Ein-/Ausgaben Fehler hervorrufen können (Datei nicht vorhanden, keine Leserechte, …), kann die Methode main nun eine Exception auslösen, was durch throws Exception deklariert wird (Eclipse schlägt diese Deklaration vor und fügt diese per Doppelklick auch in das Programm ein. Aufgabe 2.3 (Hausaufgabe, Die Crux mit den Zeichenreihen) Gegeben sei das folgende Problem: Ein Programm soll Zeichenreihen (Strings) verarbeiten, die Namen von Personen enthalten, i.a. sowohl den Vor- als auch den Nachnamen. Die Aufgabe ist, eine solche Zeichenreihe so in zwei Zeichenreihen zu teilen, dass die eine den Vornamen und die andere den Nachnamen enthält. 1. Untersuchen Sie die Java-API-Dokumentation der Klasse java.lang.String und suchen Sie Methoden, die hilfreich und/oder nötig sind, um eine Zeichenreihe mit einem Namen in zwei Zeichenreihen zu teilen, die den Vor- und den Nachnamen enthalten. 2. Nennen und erläutern Sie Probleme, Ungenauigkeiten und Unzulänglichkeiten, die Sie in der o.a. Aufgabenstellung sehen. Hinweise: Analoge Aufgabe könnte sein, Zeichenreihen, die eine Adresse enthalten, in PLZ, Ort, Straße und Hausnummer aufzuteilen. Wenn Sie nach reiflicher Überlegung der Ansicht sind, dass dies ja wohl nahezu unmöglich sei, dann testen Sie daraufhin einmal google Maps (z.B. unter "maps.google.de"). Lösung: Die Methoden split("<Trennzeichen>") oder indexOf("<Trennzeichen>") (+ substring(startIndex, endIndex)) der Klasse java.lang.String können verwendet werden, wenn das Trennzeichen bekannt ist; die erste liefert ein Array von den Teilzeichenreihen, die durch das Trennzeichen getrennt in der Eingabe vorkommen, indexOf("<Trennzeichen>") liefert das erste Vorkommen des Trennzeichens, mit substring(…, …) kann dann die Restzeichenreihe isoliert und evtl. nach weiteren Vorkommen des Trennzeichens durchsucht werden. Probleme und Ungenauigkeiten: Ein immer wiederkehrendes Problem ist, dass die Reihenfolge von Vor- und Nachnamen nicht klar ist. In manchen Kulturkreisen ist es üblich, den Namen in der Form "Nachname Vorname" anzugeben, z.B. im Chinesischen; oder noch banaler: In Formularen, in denen man Vorname und Nachname angeben soll, finden sich Eintragungen wie "Nachname, Vorname", "Nachname Vorname" oder auch "Vorname, Nachname". Ein Mensch kann ein "Müller Peter" relativ schnell richtig interpretieren, einer Maschine muss man dazu ein Menge beibringen. Und bei "Simon Fabian" ist gar nichts mehr klar. Titel sind ein weiteres typische Problem, ebenso Doppelnamen und doppelte Vornamen.