Synopsis: How do I scanf, readln, etc. in Java? http://www.cafeaulait.org/javafaq.html
Klasse Passwort -zwei Listen Name und Passwort
Zwei Felder für Namen und Passwörter sind vorgegeben.
Erstellen Sie eine Methode ausgeben(), die alle Namen nebst Passwörtern auf der Konsole ausgibt.
0. Anna f1c4e
1. Bert 123gaga
2. Kalleman babe
Erstellen Sie eine Methode ausgeben2(), die alle Namen nebst Passwörtern formatiert auf der Konsole ausgibt. Die Namen sollen 10 Zeichen breit dargestellt werden. Tipp: Mit Leerzeichen auffüllen.
1. Anna f1c4e
2. Bert 123gaga
3. Kalleman babe
Zeichen Sie ein Struktorgramm für ausgeben2().
Lösung

Entwickeln Sie die Methode check(n,p:Text):Boolean, mit Rückgabe true, wenn Name n und dazugehöriges Passwort p in den Feldern vorhanden ist, sonst Rückgabe false.
Entwickeln Sie die Methode aenderePswd(n,ap.np:Text):Boolean, zum Ändern des Passworts, dabei ist n der Name und ap,np altes und neues Passwort. Rückgabe true bei Erfolg, false sonst.
Lösung anzeigen..public class PasswortAufgaben{ static String namen[] = {"Anna","Bert","Kalle"}; static String pswd[] = {"f1c4e","123gaga","babe"}; static void ausgeben(){ int i; // Aufgabe } static void ausgeben2(){ int i,k; // Aufgabe } static boolean check(String n, String p){ int i; // Aufgabe return false; } static boolean aenderePswd(String n,String ap,String np){ int i; // Aufgabe return false; } static void ausgebenPrintf(){ int i; for(i=0;i<namen.length;i++){ System.out.printf("%2d. %-10s %s %n",i+1,namen[i],pswd[i]); } } }
Formatiertes Ausgeben mit printf
In praktisch jeder Programmierumgebung gibt es Funktionen um Ausgaben zu formatieren. Hier soll die Java-Methode printf vorgestellt werden.
1. Anna f1c4e
2. Bert 123gaga
3. Kalleman babe
public static void ausgebenPrintf(){
int i;
for(i=0;i<namen.length;i++){
System.out.printf("%2d. %-10s %s %n",i+1,namen[i],pswd[i]);
}
}
Format-Spezifizierer | Wirkung |
---|---|
%2d | Ausgabe zweistellige Dezimalzahl, rechtsbündig |
%-10s | Ausgabe als String 10 Zeichen Platz durch - linksbündig |
%s | Ausgabe String ohne besondere Formatierung |
%n | Ausgabe neue Zeile-Zeichen |
Speichern der Daten in einer Datei
Daten in Dateien (Files) zu speichern folgt diesem Prinzip:
Path pfad= Paths.get(dateipfad); // Pfad als String |
Writer aus= Files.newBufferedWriter(pfad); // Datenstrom |
aus.write("Daten schreiben"); // in den Strom schreiben |
aus.close(); // schliessen, Gepuffertes wegschreiben |
Es können dabei Probleme auftreten -Dateipfad existiert nicht, Datei ist schon durch anderes Programm geöffnet usw.
Exceptions (Ausnahmefehler)
In modernen Programmiersystemen werden Probleme in aufgerufenen Methoden durch Ausnahmefehlermeldungen (Exceptions) an die darüber liegenden Programmebenen gemeldet und dort bearbeitet.
In Java wird hierzu das try-catch-Konstrukt verwendet.
Java ist auch eine Insel / Ausnahmen müssen sein
import java.io.*; // Writer_Klasse import java.nio.file.*; // Pfad-Klasse public class PasswortDateiWrite{ static String namen[] = {"Anna","Bert","Kalle"}; static String pswd[] = {"f1c4e","123gaga","babe"}; static String dateiname = "accounts.txt"; static void ausgebenDatei(){ int i; Path pfad = Paths.get(dateiname); // Dateipfad try { // versuchen wir mal folgenden Code aus zu fuehren Writer aus = Files.newBufferedWriter(pfad); //Datenschreiber for(i=0;i<namen.length;i++){ aus.write(namen[i]+"\t"+pswd[i]+"\n"); //schreibe } aus.close(); // schliesse Datenstrom } catch (IOException e) { //falls ein IO-Ausnahmefehler System.out.println("IOException: " + e); //Fehler ausgeben } } }
Implementieren Sie den Quelltext und testen Sie die Methode ausgebenDatei().
Die ausgegebene Textdatei befindet sich im Projektordner.
Name und Passwort werden bei der Ausgabe durch ein Tabulatorzeichen "\t" getrennt.
Wenn aus.close(); weggelassen (auskommentiert) wird werden die Ausgaben ggfs. nicht abgespeichert, erst durch close() wird der Pufferspeicher im Hauptspeicher auf das Dateisystem weggeschrieben, testen Sie das.
Struktogramm mit try-catch
Ein Strukogramm zu erstellen gestaltet sich schwierig, da try-catch-Blöcke unbekannt waren als Strukogramme entwickelt wurden. Structorizer erlaubt trotzdem eine Darstellung.
String.format(..)
Formatiertes Ausgeben ist auch bei Dateien möglich: JavaInsel
aus.write(String.format("%2d. %-10s %s %n",i+1,namen[i],pswd[i]));
Erstellen Sie eine Methode ausgebenTabelle(filename:Text) für die formatierte Ausgabe einer Tabelle Nettopreis und Bruttopreis mit 19% Steuer, von 1€ bis 9€ in eine Datei filename ausgibt.
Erstellen Sie eine Methode ausgebenQuadrate(n:GZ), die Quadratzahlen von 1 bis n formatiert in eine Datei quadrate.txt ausgibt.
Link zur Vertiefung
Java ist auch eine Insel: 18 Einführung in Dateien und Datenströme
Datei auslesen
Auch beim Lesen wird zunächst ein Datenstrom geöffnet. Es können einzelne Informationen oder auch ganze Zeilen gelesen werden.
Am Ende der Datei (End Of File - EOF) gibt die readLine() Methode einen null - Verweis zurück.
Dateizeilen einlesen und ausgeben bringt die Information nicht in die Arrays zurück...
import java.io.*; // Writer_Klasse import java.nio.file.*; // Pfad-Klasse public class PasswortDateiRead{ static String dateiname = "accounts.txt"; static void leseDatei() { String zeile; Path pfad = Paths.get(dateiname); // Dateipfad try { // versuchen wir mal folgenden Code aus zu fuehren BufferedReader ein = Files.newBufferedReader(pfad); // oeffne Datenstrom while ((zeile = ein.readLine())!= null){ // solange Datensaetze vorhanden, lese Zeile System.out.println(zeile); // gib Zeile aus } ein.close(); // schliesse Datenstrom } catch (IOException e) { // falls ein IO-Ausnahmefehler auftritt tue folgendes System.out.println("IOException: " + e); // gib den Fehler auf der Konsole aus } } }
Lesen von name und pswd aus Datei
Die Namen und Passwörter sollen wieder in die Arrays eingelesen werden.
Zunächst werden jeweils 5 Strings vorgesehen.
ausgebenPrintf() gibt null bei leeren Strings aus, unterbinden Sie das.
Die aus der Datei eingelesene Zeile soll beim Tabulator zerteilt werden.
Ergänzen Sie lesePasswortDatei() entsprechend.
Lösung anzeigen..Erstellen Sie ein Struktogramm für lesePasswortDatei().
Sind mehr als 5 Datensätze in der Datei wird eine Exception ausgegeben, wie kann das verhindert werden?
Fragen:
- Was ist eine Exception?
- Wozu ist try-catch nötig?
- Warum ist die Anweisung import java.io.*; notwendig?
- Welche Schritte sind für Dateiausgabe notwendig?
- Warum müssen Dateien wieder geschlossen werden?
import java.io.*; // Writer_Klasse import java.nio.file.*; // Pfad-Klasse public class PasswortDateiRead2Aufgabe{ static String dateiname = "accounts.txt"; static String namen[] = new String[5]; // Array fuer 5 Strings static String pswd[] = new String[5]; static void lesePasswortDatei() { int datensatz = 0; // zaehlt die gelesenen Datensaetze int i; char c; String zeile; Path pfad = Paths.get(dateiname); // Dateipfad try { // versuchen wir mal folgenden Code aus zu fuehren BufferedReader ein = Files.newBufferedReader(pfad); // oeffne Datenstrom while ((zeile = ein.readLine())!= null){ // solange Datensaetze vorhanden, lese Zeile namen[datensatz]=""; pswd[datensatz]=""; for(i=0;i<zeile.length();i++){ // die Zeile bis Tab durchgehen c=zeile.charAt(i); // Aufgabe: namen einlesen } for(;i<zeile.length();i++){ // bis zum Ende pswd[datensatz]+=zeile.charAt(i); } datensatz++; } ein.close(); // schliesse Datenstrom } catch (IOException e) { // falls ein IO-Ausnahmefehler auftritt tue folgendes System.out.println("IOException: " + e); // gib den Fehler auf der Konsole aus } } static void ausgebenPrintf(){ int i; for(i=0;i<namen.length;i++){ // Aufgabe: Bei null aufhoeren System.out.printf("%2d. %-10s %s %n",i+1,namen[i],pswd[i]); } } }
Datensatzanzahl und split-Funktion
Anzahl der zu lesenen Datensätze kennen
write(..) kann auch Werte schreiben: Anzahl der Datensätze am Anfang der Datei schreiben und beim Einlesen entsprechend viele Plätze reservieren.
Eingelesene Datei-Zeilen leichter verarbeiten.
Eingelesenen String mit split(..) zerlegen.
JavaInsel
Wikipedia: Reguläre Ausdrücke
import java.io.*; import java.nio.file.*; // Pfad-Klasse public class PasswortSplit{ static String namen[] = {"Anna","Bert","Kalle"}; static String pswd[] = {"f1c4e","123gaga","babe"}; static String dateiname = "accounts.txt"; public static void ausgebenDatei() { int i; try { // versuchen wir mal folgenden Code aus zu fuehren Writer aus = Files.newBufferedWriter(Paths.get(dateiname)); aus.write(namen.length); // Anzahl der Daten speichern for(i=0;i<namen.length;i++){ aus.write(namen[i]+"\t"+pswd[i]+"\n"); //schreibe mit Tabulator getrennt } aus.close(); // schliesse Datenstrom } catch (IOException e) { // falls ein IO-Ausnahmefehler auftritt System.out.println("IOException: " + e); // gib den Fehler aus } } public static void leseDaten() { int anzahl,i=0; String zeile; String[] teile; try { BufferedReader ein = Files.newBufferedReader(Paths.get(dateiname)); anzahl = ein.read(); // lese Anzahl der Datensaetze System.out.println("Anzahl Datensaetze: "+anzahl); namen = new String[anzahl]; // erzeuge entsprechende Speicherplaetze pswd = new String[anzahl]; while ((zeile = ein.readLine())!= null){ teile = zeile.split("\t"); // zerteile Zeile namen[i]=teile[0]; pswd[i]=teile[1]; System.out.printf("%2d. %-10s %s %n",i+1,namen[i],pswd[i]); i++; } ein.close(); } catch (IOException e) { System.out.println("IOException: " + e); } } }
ArrayList
Beliebig viele Strings ohne viel Aufwand anhängen.
Array-List:JavaInsel
import java.io.*; import java.nio.file.*; import java.util.*; // List public class PasswortList{ static List<String> namen = new ArrayList<>(); static List<String> pswd = new ArrayList<>(); static String dateiname = "accounts.txt"; static void test(){ // Einfuegen zeigen namen.addAll(Arrays.asList("Anna","Bert","Kalle")); pswd.addAll(Arrays.asList("f1c4e","123gaga","babe")); } public static void leseDaten() { String zeile; String[] teile; try { BufferedReader ein = Files.newBufferedReader(Paths.get(dateiname)); while ((zeile = ein.readLine())!= null){ teile = zeile.split("\t"); // zerteile Zeile namen.add(teile[0]); pswd.add(teile[1]); } ein.close(); } catch (IOException e) { System.out.println("IOException: " + e); } } static void ausgeben(){ int i; for(i=0;i<namen.size();i++){ System.out.printf("%2d. %-10s %s %n",i+1,namen.get(i),pswd.get(i)); } } }
Eine Liste mit Account-Objekten

Zwei getrennte Listen für Namen und Passwörter sind nicht praktisch.
Die Datensätze werden jetzt in Account-Objekten gespeichert. Eine Klasse Account gibt die Datenstruktur vor.
In einer Klasse Passwortverwalter werden die Account-Objekte als Liste verwaltet.
Mit der Operation test() können Beispieldatensätze angelegt werden.
Praktische Info:
import java.io.*; import java.nio.file.*; import java.util.*; // List public class PasswortVerwalterAufg{ static List<Account> accounts = new ArrayList<Account>(); static String dateiname = "accounts.txt"; static void test(){ accounts.add(new Account("Anna","f1c4e")); accounts.add(new Account("Bert","123gaga")); accounts.add(new Account("Kalle","babe")); } static void ausgeben(){ int i; for(i=0;i<accounts.size();i++){ System.out.printf("%2d. %-10s %s %n",i+1,accounts.get(i).name, accounts.get(i).pswd); } } static void leseDaten() { String zeile; String[] teile; try { BufferedReader ein = Files.newBufferedReader(Paths.get(dateiname)); while ((zeile = ein.readLine())!= null){ teile = zeile.split("\t"); // zerteile Zeile accounts.add(new Account(teile[0],teile[1])); } ein.close(); } catch (IOException e) { System.out.println("IOException: " + e); } } static boolean check(String n, String p){ int i; // Aufgabe return false; } static boolean neuerAccount(String n,String p){ int i; // Aufgabe return true; } static void ausgebenDatei(){ int i; try { // versuchen wir mal folgenden Code aus zu fuehren // Aufgabe } catch (IOException e) { // falls ein IO-Ausnahmefehler auftritt System.out.println("IOException: " + e); // gib den Fehler aus } } }
public class Account{ String name; String pswd; Account(String n,String p){//Konstruktor name = n; pswd = p; } }
Nino 38zHHei8* Robert hGe3Uiie9 Marie nez7wwiI
Aufgaben
Eine Operation check(n:Text,p:Text):bool überprüft, ob bei existierenden Namen n das Passwort p stimmt.
Eine Operation neuerAccount(n:Text,p:Text):bool überprüft, ob der Name schon existiert, sonst wird ein neues Account-Objekt erzeugt und in die Liste hinzugefügt.
ausgebenDatei() gibt die Account-Liste in eine Datei aus.
Lösung anzeigen..Ausblick, ToDo
- Passwörter verschlüsselt speichern (Hashwerte)
- Eingaben und Konsistenzen besser überprüfen
- Passwortregeln einführen und überprüfen
- Erweitern um Nickname, Ausgabe, Dateischreiben und Lesen in Account-Klasse verlagern
- Polymorphie demonstrieren
- Als XML-Format speichern