csv Reader für Java?

alfware17

Aktives Mitglied
Ich habe kürzlich ein kleines Python-Programm entwickelt, welches eine CSV-Datei einliest und dann mache ich ein bißchen was mit den Zeilen (Menues ausgeben und Module aufrufen, das ist aber nicht wichtig). Nun wollte ich die gleiche Funktionalität auch in Java nachbilden, später auch in (Turbo-)Pascal ohne Objekte. Letzteres ist für mich im Prinzip auch nicht verhandelbar, es soll unter 16bit noch laufen. Ich habe eine 30 Jahre alte Vorlage in dBaseIV und ein wenig jüngeres schon in Pascal, welche aber 3 Nachteile hat (Textfile mehrfach lesen, logischer Fehler drin, kein execute für Module) und das ich eigentlich anpassen wollte. Auf dem Weg dorthin bin ich bei
Python gelandet und vermisse nun leider schmerzlich sowas wie den csv Reader.

Ja ich habe schon was programmiert - nicht schön aber selten, die Quelle kann ich gerne zeigen aber Ihr werdet mich zerreißen. Darum lieber meine Frage: gibt es irgendwelche Standard csv Reader, die nicht so kompliziert sind in der Anwendung? Meine Google Suche erbrachte u.a. openCSV aber ehrlich gesagt verstehe ich das noch nicht so ganz oder die Beispiele sind kompliziert.
Im Grunde habe ich in der Datei nur 6 Integer und 3 Strings, etwa 200 Zeilen, möchte die entweder als Array oder mit dynamische Liste speichern und ich bräuchte ein paar Methoden zB Existenz-Prüfung oder Untermengen als Liste.
 

Robert Zenz

Top Contributor
Im Grunde habe ich in der Datei nur 6 Integer und 3 Strings, etwa 200 Zeilen, möchte die entweder als Array oder mit dynamische Liste speichern und ich bräuchte ein paar Methoden zB Existenz-Prüfung oder Untermengen als Liste.
Wenn du sowohl Eingabeformat als auch Ausgabeformat kontrollierst, spricht nichts dagegen dass du dir "schnell" einen eigenen schreibst. Die meisten CSV-Bibliotheken sind so komplex weil CSV so komplex ist. Wenn du das aber alles nicht brauchst, und ein klar definiertes Format hast, dann kannst du dir auch genau dafuer eigene Logik schreiben, denn in Sonderfaelle und Ausnahmen wirst du nicht laufen.

Meine Google Suche erbrachte u.a. openCSV aber ehrlich gesagt verstehe ich das noch nicht so ganz oder die Beispiele sind kompliziert.
Den verstehe ich aber nicht ganz, die einfachste ist einfach nur ein String-Array aus jeder Zeile zu machen, das Beispiel ist jetzt nicht schoen, har ein paar Probleme, aber ist sehr simpel gehalten.
 

Oneixee5

Top Contributor
Letzteres ist für mich im Prinzip auch nicht verhandelbar, es soll unter 16bit noch laufen.
Den Satz verstehe ich nicht. Weder Python noch Java gibt es als 16Bit Versionen.

Auf dem Weg dorthin bin ich bei
Python gelandet und vermisse nun leider schmerzlich sowas wie den csv Reader.
Das verstehe ich auch nicht ...
The csv module defines the following functions:
csv.reader(csvfile, dialect='excel', **fmtparams)
 

alfware17

Aktives Mitglied
Den Satz verstehe ich nicht. Weder Python noch Java gibt es als 16Bit Versionen.


Das verstehe ich auch nicht ...
The csv module defines the following functions:
csv.reader(csvfile, dialect='excel', **fmtparams)
Hi ja deutsche Sprache schwere Sprache, schwerer noch als Java...
Also, ich habe bereits ein Python-Programm und nutze dort auch das csv-Modul, genauer gesagt den DictReader. Nun vermisse ich in Java etwas SO eine komfortable Lösung WIE Pythons csv.DictReader.

Ich poste nachher mal das, was ich selbst entwickelt habe.

Zum Thema 16bit - Python und Java nicht, da hast du recht. Aber (Turbo oder Free) Pascal schon. Und da mein Ziel eigentlich ein funktionierendes
Pascal Programm ist, welches ich gegenüberstelle dem dBaseIV (was natürlich auch noch läuft bei mir), beschränke ich mich bei Pascal doch gleich auf die Sprachmittel von Turbo-Pascal, obwohl ich in Lazarus/FreePascal sicher auch schicke Units finden werde.

Noch mal zur Historie:
1. dBaseIV mit Tabelle läuft im Prinzip immer noch (ich erfasse Fußballergebnisse seit 40 Jahren)
2. Umsetzung in Turbo Pascal, später FreePascal, leider mit einem Bug/Schönheitsfehler den ich nicht finde und vermutlich wegen meiner blöden Umstellung von DBF auf File/CSV
3. Python erst versucht zu portieren aus dem Pascal -> ging schief bzw sieht ebenso doof aus. Also:
4. Neu entworfen in Python mit csv-Modul und sogar objektorientiert (habe schnell und viel gelernt...)
5. CSV-Lesen in Pascal erzeugt, naja noch verbesserungswürdig, will erst Erfahrungen sammeln in Java
6. CSV-Lesen in Java erzeugt - nun ja, schau es dir an...
7.(geplant) restliche Logik in Java ergänzen (kann nicht schlimm sein, weil das Python Programm nun dank eine Python-Forums fast gut ist/läuft)
8.(geplant) restliche Logik in Pascal ergänzen und zwar nach der Java-Vorlage, WEIL ich mich direkt von Python nicht traue bzw nicht will weil ich vielleicht eh wieder auf den Bug/Schönheitsfehler laufe, ich will erstmal im "unparteiischen" Java sehen, daß und wie mein Algorithmus läuft
Nebenbei ist der Algorithmus komisch oder ungewöhnlich, aber das soll hier (noch) keine Rolle spielen.
Menues neu entwerfen mit GUI in Python und/oder Java/Pascal soll es eben nicht sein. Mir kommt es nur auf den Algorithmus/Ablauf an, so wie der da ist
 

alfware17

Aktives Mitglied
Hallo Robert Zenz und M.L. auch Euch vielen Dank. Ich zeige nun mal, was ich habe, vielleicht reicht das ja schon:


Java:
package csvReader;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CSVReader {
    private static final int MAX_RECORDS = 200;

    // TRecord-Klasse entspricht dem Pascal Record
    static class TRecord {
        int M1, M2, M3, N1, N2, L1;
        String PROG, BEZEICHNER, CODE;

        // Konstruktor für TRecord
        TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) {
            this.M1 = m1;
            this.M2 = m2;
            this.M3 = m3;
            this.PROG = prog;
            this.BEZEICHNER = bezeichner;
            this.CODE = code;
            this.N1 = n1;
            this.N2 = n2;
            this.L1 = l1;
        }

        @Override
        public String toString() {
            return "M1=" + M1 + ", M2=" + M2 + ", M3=" + M3 + ", PROG=" + PROG + ", BEZEICHNER=" + BEZEICHNER + ", CODE=" + CODE + ", N1=" + N1 + ", N2=" + N2 + ", L1=" + L1;
        }
    }

    // TDatei-Klasse entspricht der Pascal-Struktur mit RecordCount
    static class TDatei {
        List<TRecord> records = new ArrayList<>();
    }

    static TDatei datei = new TDatei(); // CSV-Daten
    static TDatei matchingRecords = new TDatei(); // Gefundene Sätze

    // Hilfsfunktion zur Konvertierung von String in Integer (Fehler wird als 0 behandelt)
    static int strToInt(String s) {
        try {
            return Integer.parseInt(s.trim());
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    // Funktion zum Extrahieren eines Feldes aus einer CSV-Zeile (mit Semikolon als Trennzeichen)
//    static String csvStrip(String line) {
//        int semicolonPos = line.indexOf(';');
//        if (semicolonPos >= 0) {
//            String field = line.substring(0, semicolonPos);
//            return line.substring(semicolonPos + 1);
//        } else {
//            return line; // Letztes Feld
//        }
//    }

    // Funktion, die einen Satz basierend auf dem Index zurückgibt
    static boolean getRecordByIndex(int index, TRecord[] rec) {
        if (index >= 0 && index < datei.records.size()) {
            rec[0] = datei.records.get(index);
            return true;
        }
        return false;
    }

    // Funktion, die alle Sätze zurückgibt, die zu M1 und M2 passen
    static boolean getRecordsByKeys(int key1, int key2, TDatei resultRecords) {
        resultRecords.records.clear();
        boolean found = false;
        for (TRecord record : datei.records) {
            if (record.M1 == key1 && record.M2 == key2) {
                resultRecords.records.add(record);
                found = true;
            }
        }
        return found;
    }

    // CSV-Datei einlesen und die Daten in das Array laden, 1. Zeile überspringen
    static void loadCSV(String fileName) throws IOException {
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            String line = br.readLine(); // Überspringe die erste Zeile (Header)
            while ((line = br.readLine()) != null && datei.records.size() < MAX_RECORDS) {
                String[] fields = line.split(";");

                // Parst die Zeile und fügt den Satz der Liste hinzu
                TRecord record = new TRecord(
                    strToInt(fields[0]), // M1
                    strToInt(fields[1]), // M2
                    strToInt(fields[2]), // M3
                    fields[3],           // PROG
                    fields[4],           // BEZEICHNER
                    fields[5],           // CODE
                    strToInt(fields[6]), // N1
                    strToInt(fields[7]), // N2
                    strToInt(fields[8])  // L1
                );
                datei.records.add(record);
            }
        }
    }

    public static void main(String[] args) {
        try {
            loadCSV("daten.csv");

            // Test: Suche nach einem Datensatz über den Index
            TRecord[] rec = new TRecord[1];
            boolean found = getRecordByIndex(4, rec); // Index 4 (entspricht dem 5. Satz)
            if (found) {
                System.out.println("Datensatz 5: " + rec[0]);
            } else {
                System.out.println("Datensatz nicht gefunden.");
            }

            // Test: Suche nach Sätzen mit M1=2 und M2=3
            found = getRecordsByKeys(2, 3, matchingRecords);
            if (found) {
                System.out.println("Gefundene Datensätze für M1=2, M2=3:");
                for (TRecord record : matchingRecords.records) {
                    System.out.println(record);
                }
            } else {
                System.out.println("Keine Datensätze für M1=2, M2=3 gefunden.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Ein paar Methoden und etwas Logik brauche ich dann schon noch, aber die Datenbasis dürfte ich erstmal haben. Nicht wundern, ich habe die eine Methode csvStrip noch als Kommentar drin gelassen um zu zeigen, womit ich mich in den verschiedenen Sprachen herumschlagen darf.
Das csvStrip brauche ich in Pascal, ich benutze es auch in anderen Sprachen. In Java habe ich immerhin schon das .split(';') welches es im Prinzip auch in Python tun würde aber da bin ich noch bequemer und nutze das csv.DictReader. Ich muß dann aber wieder vom Komfortablen zurück gehen zur Handarbeit bzw mir in Pascal einiges selber schreiben. Habe ich nun mein Problem/meine Vorgehensweise deutlich gemacht?
 

Oneixee5

Top Contributor
Also du hast Daten von 40 Jahren und Daten in einem alten Datenbankformat. Warum lernst du da 60 Programmiersprachen? Wenn du immer etwas neues fummelst wirst du nie mit irgend etwas fertig.
Wenn Daten in einem alten DB-Format vorhanden sind, dann ist doch das Naheliegendste die Daten in ein neues DB-Format umzuwandeln. So kannst du bspw. mit SQL zugreifen, filtern, umwandeln ....
DB-Programme gibt es zu Hauf und du kannst da GUIs in 1000 Programmiersprachen drumherum bauen , immer auf der gleichen Datenasis. Fußball-Ergebnisse wären auch was fürs Web.
 

alfware17

Aktives Mitglied
Also du hast Daten von 40 Jahren und Daten in einem alten Datenbankformat. Warum lernst du da 60 Programmiersprachen? Wenn du immer etwas neues fummelst wirst du nie mit irgend etwas fertig.
Wenn Daten in einem alten DB-Format vorhanden sind, dann ist doch das Naheliegendste die Daten in ein neues DB-Format umzuwandeln. So kannst du bspw. mit SQL zugreifen, filtern, umwandeln ....
DB-Programme gibt es zu Hauf und du kannst da GUIs in 1000 Programmiersprachen drumherum bauen , immer auf der gleichen Datenasis. Fußball-Ergebnisse wären auch was fürs Web.

Es ist schlimmer als du ahnst - ich halte mir die Daten in Excel, der Weg wie sie da hineinkommen sei mal dahingestellt und hat sich auch mehrfach geändert, am Anfang war zB Abtippen per Hand. Die exportiere ich dann nach dBase und mein Programm zeigt sie mir. Einfach nur um zu sehen, ob es das virtuell oder real aufgerufene dBase noch tut.

In Java wollte ich das eigentlich recht umfangreiche dBase Programm sowieso nie machen, du hast recht, es gibt weit Besseres und auch im Web.
Mir ging es nur um die Idee von damals, das Menue selbst auch in der Datenbank äh Tabelle zu verwalten, so kann das aufgerufene Modul bzw die Parameter verwaltet werden. Um das alles geht es hier nicht, nur um das Stück Lesen bzw Rufen der Datenbank äh Tabelle nun CSV.

Mit 60 Programmiersprachen könntest du mittlerweile ziemlich nah dran sein. Und ja, es gibt schon 1000 Ligaverwaltungssysteme aber ich glaube nur meins in dBase hatte damals so Orakel-Funktionen, sprich Ergebnisse voraussagen und daß es zu einem parallelen Excel-Projekt kompatibel ist,
will ich auch nicht weggeben.

Hast du zu meinem Java etwas (nicht) zu meckern? Wahrscheinlich mehr meckern als nicht meckern
 

Oneixee5

Top Contributor
Ich werde mal kurz anreisen, wie man mit CSV-Dateien in Java umgehen kann. Verwenden werde ich dazu: https://github.com/h2database/h2database Die CSV-Datei soll "test.csv" heißen.

Hier wäre eine einfache Ausgabe der Daten außerhalb der DB:
Java:
import java.sql.*;
import org.h2.tools.*;

public class TestCsv {
    public static void main(String[] args) throws Exception {
        ResultSet rs = new Csv().read("data/test.csv", null, null);
        ResultSetMetaData meta = rs.getMetaData();
        while (rs.next()) {
            for (int i = 0; i < meta.getColumnCount(); i++) {
                System.out.println(
                    meta.getColumnLabel(i + 1) + ": " +
                    rs.getString(i + 1));
            }
            System.out.println();
        }
        rs.close();
    }
}

Wenn man nur bestimmte Datensätze haben möchte, dann kann man auch filtern:
Java:
SELECT * FROM CSVREAD('test.csv') WHERE SPALTE_A = 'Ein Wert' AND SPALTE_B = 'Ein anderer Wert';
Allerdings ist es besser nicht die Abfragen auf der CSV-Datei durchzuführen, sonder auf einer Datenbanktabelle innerhalb der DB. Dazu muss man die Daten einmalig in die DB übernehmen. man verbindet sich und macht das etwa so:
SQL:
CREATE TABLE TEST AS SELECT * FROM CSVREAD('test.csv');
-- und auch weitere ...
CREATE TABLE TEST_1 AS SELECT * FROM CSVREAD('test1.csv');
CREATE TABLE TEST_2 AS SELECT * FROM CSVREAD('test2.csv');
CREATE TABLE TEST_3 AS SELECT * FROM CSVREAD('test3.csv');
Jetzt kann man die Daten sogar noch joinen - also miteinander verknüpfen und filtern:
SQL:
SELECT * FROM TEST WHERE SPALTE_JAHR = 2004;
-- alle Datensätze aus 2004
-- oder auch
SELECT *
FROM TEST as t1
  INNER JOIN TEST_1 as t2 on t2.SPALTE_NAME = t1.SPALTE_NAME
WHERE t1.SPALTE_JAHR = 2004;
-- hier wären die Datensätze aus beiden Tabellen nebeneinander, welche den gleichen Namen in der SPALTE_NAME haben

Wie du siehst könntest du mit den richtigen Mitteln dein Programm von oben mit sehr wenigen Zeilen Code schreiben und das noch mit deutlich mehr Möglichkeiten. Weniger Code macht alles einfacher und übersichtlicher und hilft dabei Fehler zu vermeiden.
 

Barista

Top Contributor
Nun wollte ich die gleiche Funktionalität auch in Java nachbilden, später auch in (Turbo-)Pascal ohne Objekte. Letzteres ist für mich im Prinzip auch nicht verhandelbar, es soll unter 16bit noch laufen.
Ich könnte mir vorstellen, dass unter aktuellem Windows immer noch solche Programme und natürlich auch die alten IDEs (Tools) laufen,
denn bei Microsoft legt man großen Wert auf Rückwärtskompatibilität.

Es gab übrigens auch ein objektorientiertes Turbo-Pascal. Erst bracht Microsoft Object-Pascal raus und dann kam ziemlich schnell ein OOP-Pascal von Borland.

Das OOP-Pascal von Borland hatte eine Lib dabei, mit der man mausbedienbare Oberflächen in Textmodus erstellen konnte (SAA CUA), habe ich leider nie benutzt, weil ich auf Clipper gearbeitet habe.
 

Oneixee5

Top Contributor
es soll unter 16bit noch laufen
Ich frage mich - wozu? Wer programmiert denn heute noch Programme in 16Bit TP? Das macht doch gar keinen Sinn. Die Hardware gibt es gar nicht mehr, die Plattform wird noch für begrenzte Zeit durch Software simuliert. Wenn ich die Optik von TP haben möchte, kann ich auch CSS nehmen. Es gibt bestimmt schon Freaks die so etwas machen. Wenn ich noch alte Software besitzen würde, kann ich die zum Test noch betreiben. Weiterentwickeln macht aber keinen Sinn. Wenn jemand über 40 Jahre Daten sammelt, dann liegt dem Sammler doch etwas daran. Dann wäre es doch sinnlos, diese Date in ein System einzuschließen, welches niemand anderes benutzen kann. Im Interesse des Sammlers wäre doch eher, die Daten für mögliche Nachfolger verfügbar zu halten oder die Daten anderweitig zu nutzen. Sei es finanziell, statistisch oder bildend. Beides wird aber nicht funktionieren, wenn man Hard- oder Software verwendet, über die niemand sonst verfügt.
 

alfware17

Aktives Mitglied
Meckern ist leicht. Man sieht das du kein Java-Profi bist. Du willst das nur zum Eigenbrauch, von daher muss man die Latte nicht so hoch hängen. Aber ja, das Programm geht auch einfacher, schöner und wesentlich kürzer.
Wie jetzt, "wesentlich kürzer"? Meine Pascal-Version hat jetzt so ca 150 Zeilen - ok da muß man so einiges erst erfinden, zB die Liste


Java:
PROGRAM csvread_obj;

TYPE
   PSatz = ^TSatz;
   TSatz = OBJECT
      M1, M2, M3, N1, N2, L1: INTEGER;
      PROG, BEZEICHNER, CODE: STRING[50];
      Folge: PSatz;

      PROCEDURE Init(M1_, M2_, M3_ : INTEGER; PROG_, BEZEICHNER_, CODE_: STRING; N1_, N2_, L1_: INTEGER);
      PROCEDURE Zeigen;
   END;

   TDaten = OBJECT
      Kopf, Fuss: PSatz;
      Anzahl: INTEGER;

      PROCEDURE Init;
      PROCEDURE Hinzufuegen(VAR Satz: TSatz);
      PROCEDURE Zeigen;
      PROCEDURE Freigeben;
      FUNCTION LesenSatzbyM(M1_, M2_, M3_: INTEGER; VAR Satz: TSatz): BOOLEAN;
      FUNCTION LesenDatenbyM(M1_, M2_: Integer; VAR Bereich: TDaten): BOOLEAN;
   END;

PROCEDURE TSatz.Init(M1_, M2_, M3_ : INTEGER; PROG_, BEZEICHNER_, CODE_: STRING; N1_, N2_, L1_: INTEGER);
BEGIN
   M1 := M1_; M2 := M2_; M3 := M3_;
   N1 := N1_; N2 := N2_; L1 := L1_;
   PROG := PROG_; BEZEICHNER := BEZEICHNER_; CODE := CODE_;
   Folge := NIL;
END;

PROCEDURE TSatz.Zeigen;
BEGIN
   WriteLn('M1=', M1, ', M2=', M2, ', M3=', M3, ', PROG=', PROG,
           ', BEZ=', BEZEICHNER, ', CODE=', CODE, ', N1=', N1, ', N2=', N2, ', L1=', L1);
END;

PROCEDURE TDaten.Init;
BEGIN
   Kopf := NIL; Fuss := NIL; Anzahl := 0;
END;

PROCEDURE TDaten.Hinzufuegen(VAR Satz: TSatz);
VAR Neues: PSatz;
BEGIN
   New(Neues);
   Neues^ := Satz;
   Neues^.Folge := NIL;
   IF Kopf = NIL THEN
      Kopf := Neues
   ELSE
      Fuss^.Folge := Neues;
   Fuss := Neues;
   INC(Anzahl);
END;

PROCEDURE TDaten.Zeigen;
VAR Zeiger: PSatz;
BEGIN
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      Zeiger^.Zeigen;
      Zeiger := Zeiger^.Folge;
   END;
END;

PROCEDURE TDaten.Freigeben;
VAR Zeiger, Temp: PSatz;
BEGIN
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      Temp := Zeiger^.Folge;
      Dispose(Zeiger);
      Zeiger := Temp;
   END;
   Kopf := NIL; Fuss := NIL; Anzahl := 0;
END;

FUNCTION TDaten.LesenSatzbyM(M1_, M2_, M3_: INTEGER; VAR Satz: TSatz): BOOLEAN;
VAR Zeiger: PSatz;
BEGIN
   LesenSatzbyM := False;
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      IF (Zeiger^.M1 = M1_) AND (Zeiger^.M2 = M2_) AND (Zeiger^.M3 = M3_) THEN BEGIN
         Satz := Zeiger^;
         LesenSatzbyM := True;
         Exit;
      END;
      Zeiger := Zeiger^.Folge;
   END;
END;

FUNCTION TDaten.LesenDatenbyM(M1_, M2_: INTEGER; VAR Bereich: TDaten): BOOLEAN;
VAR Zeiger: PSatz;
BEGIN
   Bereich.Freigeben;
   LesenDatenbyM := False;
   Zeiger := Kopf;
   WHILE Zeiger <> NIL DO BEGIN
      IF (Zeiger^.M1 = M1_) AND (Zeiger^.M2 = M2_) THEN BEGIN
         Bereich.Hinzufuegen(Zeiger^);
         LesenDatenbyM := True;
      END;
      Zeiger := Zeiger^.Folge;
   END;
END;

PROCEDURE LoadCSV(CONST FileName: STRING; VAR Daten: TDaten);
VAR
   CSVFile: TEXT;
   Zeile: STRING;
   NeuerSatz: TSatz;

   FUNCTION Str2Int(S: STRING): INTEGER;
   VAR w, Zahl: INTEGER;
   BEGIN
      Val(S, Zahl, w);
      IF w = 0 THEN Str2Int := Zahl
      ELSE Str2Int := -1;
   END;

   FUNCTION Strip(VAR Zeile: STRING): STRING;
   VAR k: INTEGER;
   BEGIN
      k := Pos(';', Zeile);
      IF k = 0 THEN k := LENGTH(Zeile) + 1;
      Strip := Copy(Zeile, 1, k - 1);
      Zeile := Copy(Zeile, k + 1, 255);
   END;

BEGIN
   Daten.Freigeben;
   Assign(CSVFile, FileName); Reset(CSVFile);
   ReadLn(CSVFile, Zeile);
   WHILE NOT EOF(CSVFile) DO BEGIN
      ReadLn(CSVFile, Zeile);
      Neuersatz.Init(Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)),
                     Strip(Zeile), Strip(Zeile), Strip(Zeile),
                     Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)), Str2Int(Strip(Zeile)));
      Daten.Hinzufuegen(NeuerSatz);
   END;
   Close(CSVFile);
END;

VAR
   Daten, Auswahl: TDaten;
   EinzelSatz: TSatz;

BEGIN
   Daten.Init; Auswahl.Init;
   LoadCSV('daten.csv', Daten);
   (* Daten.Zeigen; *)
   IF Daten.LesenSatzbyM(0, 0, 9, EinzelSatz) THEN
      WriteLn('Datensatz 0 0 9 : ', EinzelSatz.BEZEICHNER, ' ', EinzelSatz.CODE)
   ELSE
      WriteLn('Datensatz nicht gefunden.');
   IF Daten.LesenDatenbyM(0, 6, Auswahl) THEN BEGIN
      WriteLn('Gefundene Datensätze für M1=0, M2=6:');
      Auswahl.Zeigen;
   END ELSE
      WriteLn('Keine Datensätze für M1=0, M2=6 gefunden.');
   Daten.Freigeben; Auswahl.Freigeben;
   ReadLn;
END.


Wenigstens hat mir das mein 16bit Pascal schon mal abgenommen... In Java muß ich mir das mal anschauen, auch was du gemacht hast
 

alfware17

Aktives Mitglied
Deine Programmfragmente(?) mit dem SQL habe ich jetzt nicht 100% verstanden und was du da machst? Das CSVREAD ist schon fertig?
Und naja, wenn SQL habe ich bisher SQLite angebunden, aber das sind schon ein paar Zeilen Code in Java, bis es los geht...
 

alfware17

Aktives Mitglied
Ja was ist jetzt schlimmer? Ob Excel oder CSV oder DBase - Generationen haben schon damit gearbeitet, das ist kein Grund für irgendwelche Fehler und man kann das alles in DB's aufnehmen und auch wieder rausschreiben.
Das habe ich nun nicht verstanden. Ich meinte mit schlimmer nur meine historische Toolsammlung und daß ich mir per Internet und Excel die Daten für das dBase Programm zusammenbastele
 

alfware17

Aktives Mitglied
Ich könnte mir vorstellen, dass unter aktuellem Windows immer noch solche Programme und natürlich auch die alten IDEs (Tools) laufen,
denn bei Microsoft legt man großen Wert auf Rückwärtskompatibilität.

Es gab übrigens auch ein objektorientiertes Turbo-Pascal. Erst bracht Microsoft Object-Pascal raus und dann kam ziemlich schnell ein OOP-Pascal von Borland.

Das OOP-Pascal von Borland hatte eine Lib dabei, mit der man mausbedienbare Oberflächen in Textmodus erstellen konnte (SAA CUA), habe ich leider nie benutzt, weil ich auf Clipper gearbeitet habe.

Nein, seit Vista (15 Jahre?) läuft kein 16bit mehr im Windows 7,8.10,11. Muß es auch nicht - ich habe meine DOSBOX und unter Virtalbox mein Win XP oder Win 7/32 je nachdem. Ich rufe die originalen dBaseIV und Turbo-Pascal auf, wenn ich ganz sicher gehen will, habe ich in der Virtualbox auch mein MS-DOS und das erzählt mir dann, was noch alles nicht geht oder den Speicher sprengt.

Versteht mich nicht falsch, ich mache das nur als Hobby. Ich habe zB da ein Programm da sind die Quellen für Linux32/64, Win16/32/64 zu 90% kompatibel und der Rest wird über Compilerschalter konfiguriert.

Ich brauche das 16bit Programm nicht unbedingt, aber ich hätte es gern.

Und ja - ich habe sowohl Borlands oo-Pascal kennengelernt als auch die Nachfolger Delphi und Lazarus kennengelernt. Mit letzterem arbeite ich normalerweise. Momentan ist mir aber irgendwie mehr nach Java und Python und im Falle des vorgestellten dBaseIV Algorithmus eigentlich nur danach es in allen 3 Sprachen auszudrücken. Es ist mir schon klar, es wird immer unterschiedlich aussehen und unterschiedlich im Programmier-Komfort aber ich kann ja dabei lernen.
 

alfware17

Aktives Mitglied
Ich frage mich - wozu? Wer programmiert denn heute noch Programme in 16Bit TP? Das macht doch gar keinen Sinn. Die Hardware gibt es gar nicht mehr, die Plattform wird noch für begrenzte Zeit durch Software simuliert. Wenn ich die Optik von TP haben möchte, kann ich auch CSS nehmen. Es gibt bestimmt schon Freaks die so etwas machen. Wenn ich noch alte Software besitzen würde, kann ich die zum Test noch betreiben. Weiterentwickeln macht aber keinen Sinn. Wenn jemand über 40 Jahre Daten sammelt, dann liegt dem Sammler doch etwas daran. Dann wäre es doch sinnlos, diese Date in ein System einzuschließen, welches niemand anderes benutzen kann. Im Interesse des Sammlers wäre doch eher, die Daten für mögliche Nachfolger verfügbar zu halten oder die Daten anderweitig zu nutzen. Sei es finanziell, statistisch oder bildend. Beides wird aber nicht funktionieren, wenn man Hard- oder Software verwendet, über die niemand sonst verfügt.
Die Daten sind in dem Fall nicht besonders wertvoll - ich habe sie wie gesagt parallel oder konvertierbar auch in Excel und dort arbeiten auch einige Auswerte-Programme. Was mir von Wert ist, ist das alte dBase Programm und daß ich es immer mal wieder ans Laufen kriege, wobei solange wie es Virtualbox gibt, geht das ja. Ich werde da ja auch kaum weiter entwickeln - wenn ich was für 16bit mache dann eher aus Neugier, ob meine 32/64bit Programme in Lazarus es eventuell auch in 16bit schaffen können mit geringer Abrüstung, Das gleiche mache ich übrigens auch in Linux, wo ich null Lust auf Neuentwicklung habe, das sind alles Klone bzw Adaptionen der Windows Lösungen.

Und zu deinem letzten Satz: ja da hast du leider recht. Ich bin uralt und ein Dinosaurier, meine Systemlandschaft und meine Programme sterben mit mir aus.
 

mihe7

Top Contributor
Wie jetzt, "wesentlich kürzer"? Meine Pascal-Version hat jetzt so ca 150 Zeilen - ok da muß man so einiges erst erfinden, zB die Liste
Naja, in Java gibt es z. B. record, damit kannst Du statt
Java:
    static class TRecord {
        int M1, M2, M3, N1, N2, L1;
        String PROG, BEZEICHNER, CODE;

        // Konstruktor für TRecord
        TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) {
            this.M1 = m1;
            this.M2 = m2;
            this.M3 = m3;
            this.PROG = prog;
            this.BEZEICHNER = bezeichner;
            this.CODE = code;
            this.N1 = n1;
            this.N2 = n2;
            this.L1 = l1;
        }

        @Override
        public String toString() {
            return "M1=" + M1 + ", M2=" + M2 + ", M3=" + M3 + ", PROG=" + PROG + ", BEZEICHNER=" + BEZEICHNER + ", CODE=" + CODE + ", N1=" + N1 + ", N2=" + N2 + ", L1=" + L1;
        }
    }

einfach
Java:
    record TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) { }

schreiben. Achtung: records sind immutable.

Wobei "kürzer" für mich jetzt nicht unbedingt ein Argument wäre. Jedenfalls kann man damit etwas wie
Java:
class CsvReader {
    public record TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) { }

    private static final int MAX_RECORDS = 200;

    private int maxRecords;

    public CsvReader() {
        maxRecords = MAX_RECORDS;
    }

    public CsvReader(int maxRecords) {
        this.maxRecords = maxRecords;
    }

    static TRecord newRecord(String string) {
        String[] parts = string.split(";");
        return new TRecord(intToString(parts[0]), intToString(parts[1]), intToString(parts[2]),
                    parts[3], parts[4], parts[5],
                    intToString(parts[6]), intToString(parts[7]), intToString(parts[8]));
    }

    static int intToString(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException ex) {
            return 0;
        }
    }

    public List<TRecord> read(Path csvFile) throws IOException {
        return Files.lines(csvFile).skip(1).limit(maxRecords).map(CsvReader::newRecord).toList();
    }
}

realisieren und mit
Java:
var records = new CsvReader().read(Path.of("C:\\Path\\to\\csvFile.csv"));
// oder, wenn man z. B. max. 500 Zeilen lesen möchte
var records = new CsvReader(500).read(Path.of("C:\\Path\\to\\csvFile.csv"));
lassen sich dann die Sätze einlesen.
 

Oneixee5

Top Contributor
Naja, in Java gibt es z. B. record, damit kannst Du statt
Java:
    static class TRecord {
        int M1, M2, M3, N1, N2, L1;
        String PROG, BEZEICHNER, CODE;

        // Konstruktor für TRecord
        TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) {
            this.M1 = m1;
            this.M2 = m2;
            this.M3 = m3;
            this.PROG = prog;
            this.BEZEICHNER = bezeichner;
            this.CODE = code;
            this.N1 = n1;
            this.N2 = n2;
            this.L1 = l1;
        }

        @Override
        public String toString() {
            return "M1=" + M1 + ", M2=" + M2 + ", M3=" + M3 + ", PROG=" + PROG + ", BEZEICHNER=" + BEZEICHNER + ", CODE=" + CODE + ", N1=" + N1 + ", N2=" + N2 + ", L1=" + L1;
        }
    }

einfach
Java:
    record TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) { }

schreiben. Achtung: records sind immutable.

Wobei "kürzer" für mich jetzt nicht unbedingt ein Argument wäre. Jedenfalls kann man damit etwas wie
Java:
class CsvReader {
    public record TRecord(int m1, int m2, int m3, String prog, String bezeichner, String code, int n1, int n2, int l1) { }

    private static final int MAX_RECORDS = 200;

    private int maxRecords;

    public CsvReader() {
        maxRecords = MAX_RECORDS;
    }

    public CsvReader(int maxRecords) {
        this.maxRecords = maxRecords;
    }

    static TRecord newRecord(String string) {
        String[] parts = string.split(";");
        return new TRecord(intToString(parts[0]), intToString(parts[1]), intToString(parts[2]),
                    parts[3], parts[4], parts[5],
                    intToString(parts[6]), intToString(parts[7]), intToString(parts[8]));
    }

    static int intToString(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException ex) {
            return 0;
        }
    }

    public List<TRecord> read(Path csvFile) throws IOException {
        return Files.lines(csvFile).skip(1).limit(maxRecords).map(CsvReader::newRecord).toList();
    }
}

realisieren und mit
Java:
var records = new CsvReader().read(Path.of("C:\\Path\\to\\csvFile.csv"));
// oder, wenn man z. B. max. 500 Zeilen lesen möchte
var records = new CsvReader(500).read(Path.of("C:\\Path\\to\\csvFile.csv"));
lassen sich dann die Sätze einlesen.
Filter auf die Liste sind auch nicht viel mehr Aufwand.
 

Oneixee5

Top Contributor
aber das find ich gut - intToString:
Java:
    static int intToString(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException ex) {
            return 0;
        }
    }
 

mihe7

Top Contributor
Filter auf die Liste sind auch nicht viel mehr Aufwand.
@alfware17 man könnte statt der Liste den Stream zurückgeben (z. B. in einer zweiten Methode records), dann lässt sich z. B. schreiben
Java:
var records = new CsvReader(500).records(Path.of("C:\\Path\\to\\csvFile.csv")).filter(r -> r.m1() == 0).toList();
um nur die TRecord-Instanzen in der Liste zu erhalten, deren m1 gleich 0 ist.
 

alfware17

Aktives Mitglied
Danke euch schon erstmal für die kurze Variante zum csvReader, ich werde sie am WE in mein Programm einbauen. Nunja, das ist natürlich viel eleganter. Das map kannte ich noch gar nicht und das filter auch nicht. Nach Sichtung meines Python Programms habe ich festgestellt daß ich die eine Methode (suche nach Index) gar nicht brauche für den Algorithmus sondern nur eine mit Vergleich aller 3 M (Existenz bzw 1 Zeile) und eine nur Vergleich mit M1 und M2 (Unterliste). In Pascal bin ich schon weiter mit dem Umbau - komme aber immer wieder durcheinander, da das ganze auch keine hohe Prio hat. Aber vielleicht jetzt zu den Feiertagen :)
 

mihe7

Top Contributor
map und filter sind Methoden von java.util.stream.Stream. Die Klasse CsvReader liest halt einfach die Datensätze aus einer Datei. Nicht mehr, nicht weniger und was anderes sollte die Klasse auch nicht machen. TRecord sollte in eine separate TRecord.java verschoben werden. Für alles andere kannst Du andere Klassen bauen. Für einen indizierten Zugriff kannst Du z. B. Collectors.toMap (unique index) und Collectors.groupingBy (non-unique index) verwenden. Das führt aber jetzt etwas zu weit, daher nur mal als Stichworte.
 

alfware17

Aktives Mitglied
Ich habe nun mein Programm in Java, Python und Pascal abgeschlossen, letzteres war der größte Kampf, weil ich nun durch Java und Python auf den Geschmack gekommen war und unbedingt auch ArrayLists und Stack und generell OO haben wollte und das auch im eigentlichen Zielsystem 16bit/Turbo-Pascal, wo ich mir erstmal diese ADT schaffen mußte. So ganz zufrieden oder glücklich bin ich mit allen drei Lösungen nicht, aber immerhin habe ich sehr viel gelernt dabei.

Anbei nun der Java-Quellcode, wobei ich sagen muß ich habe einige Stilmittel nur eingebaut, weil sie hier bzw von meiner KI genannt wurden, von alleine wäre ich zB auf die Filter nie gekommen (obwohl ich sie gut finde). Die enum dagegen ist wohl eher eine Schnapsidee...

Java:
undefinedpackage freiburg;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Scanner;
import java.util.Stack;
import java.util.stream.Collectors;

class Freiburg {

    enum ProgTyp { PROGRAMM("P"), MENUE("M"), DIVERSE("D");
        private String code;
        ProgTyp(String code) { this.code = code; }
        public String getCode() { return code; }

        public static ProgTyp fromCode(String code) {
            for (ProgTyp progTyp : values()) {
                if (progTyp.code.equalsIgnoreCase(code))
                   return progTyp;
            }
            throw new IllegalArgumentException("Ungültiger Programmtyp: " + code);
        }
    }

    static class TEintrag {
        int M1, M2, M3, N1, N2, L1;
        ProgTyp progTyp;
        String BEZEICHNER, CODE;

        TEintrag(int M1, int M2, int M3, ProgTyp progTyp, String BEZEICHNER, String CODE, int N1, int N2, int L1) {
          this.M1 = M1; this.M2 = M2; this.M3 = M3;
          this.progTyp = progTyp; this.BEZEICHNER = BEZEICHNER; this.CODE = CODE;
          this.N1 = N1; this.N2 = N2; this.L1 = L1;
        }
        void kopiereVon(TEintrag quelle) {
          this.M1 = quelle.M1; this.M2 = quelle.M2; this.M3 = quelle.M3;
          this.progTyp = quelle.progTyp; this.BEZEICHNER = quelle.BEZEICHNER; this.CODE = quelle.CODE;
          this.N1 = quelle.N1; this.N2 = quelle.N2; this.L1 = quelle.L1;
        }
    }

    static class TMenueManager {
        private static final String HAUPTMENUE_BEZEICHNUNG = "Hauptmenue";
        
        List<TEintrag> gesamt = new ArrayList<>();
        Stack<TEintrag> mStack = new Stack<>();
        int m1 = 0, m2 = 0;
        String bezeichnung = HAUPTMENUE_BEZEICHNUNG;
        boolean menueAngezeigt = false;

        Optional<TEintrag> findeMenuepunkt(int m1, int m2, int m3) {
            return gesamt.stream()
                    .filter(eintrag -> eintrag.M1 == m1 && eintrag.M2 == m2 && eintrag.M3 == m3)
                    .findFirst();
        }

        boolean hatNachfolgeMenue(int n1, int n2) {
            return gesamt.stream().anyMatch(eintrag -> eintrag.M1 == n1 && eintrag.M2 == n2);
        }

        List<TEintrag> aktuelleMenuepunkte(int m1, int m2) {
            return gesamt.stream()
                    .filter(eintrag -> eintrag.M1 == m1 && eintrag.M2 == m2)
                    .collect(Collectors.toList());
        }

        void zeigeMenue() {
            List<TEintrag> menuepunkte = aktuelleMenuepunkte(m1, m2);
            if (menuepunkte.isEmpty()) {
                System.out.println("Fehler: Menuezeilen nicht vorhanden.");
            } else {
                System.out.println("\n" + bezeichnung + ":");
                for (TEintrag punkt : menuepunkte) {
                    System.out.println(String.format("%d: %s", punkt.M3, punkt.BEZEICHNER));
                    for (int i = 0; i < punkt.L1; i++) System.out.println();
                }
                System.out.println("0: Zurueck");
            }
        }

        boolean bearbeiteAuswahl(int auswahl) {
            if (auswahl == 0) {
                menueAngezeigt = false;
                if (mStack.isEmpty()) {
                    System.out.println("Programmende.");
                    return true;
                }
                TEintrag temp = mStack.pop();
                m1 = temp.M1; m2 = temp.M2;
                bezeichnung = temp.BEZEICHNER;
                return false;
            }

            Optional<TEintrag> optionalPunkt = findeMenuepunkt(m1, m2, auswahl);
            if (!optionalPunkt.isPresent()) {
                System.out.println("Ungueltige Auswahl. Keine Eintraege fuer das gewaehlte Menue.");
                return false;
            }
            
            TEintrag punkt = optionalPunkt.get();
            bezeichnung = punkt.BEZEICHNER;
            if (punkt.progTyp.equals(ProgTyp.PROGRAMM)) {
                System.out.println("Starte Programm: " + punkt.CODE);
            } else if (punkt.progTyp.equals(ProgTyp.MENUE)) {
                if (hatNachfolgeMenue(punkt.N1, punkt.N2)) {
                    mStack.push(punkt);
                    m1 = punkt.N1; m2 = punkt.N2;
                    menueAngezeigt = false;
                } else {
                    System.out.println("Ungueltige Auswahl. Aufgerufenes Menue nicht gefunden.");
                }
            } else {
                System.out.println("Fehler: Falscher Programmcode.");
            }
            return false;
        }

        void fuehreMenueAus() {
            try (Scanner scanner = new Scanner(System.in)) {
                while (true) {
                    if (!menueAngezeigt) {
                        zeigeMenue();
                        menueAngezeigt = true;
                    }
                    System.out.print("Auswahl: ");
                    try {
                        int auswahl = Integer.parseInt(scanner.nextLine());
                        if (bearbeiteAuswahl(auswahl))
                            break;
                    } catch (NumberFormatException e) {
                        System.out.println("Ungueltige Eingabe. Bitte geben Sie eine Zahl ein.");
                    }
                }
            }
        }

        void loadCSV(String fileName) {
            try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
                br.lines().skip(1).forEach(line -> {
                    try {
                        String[] parts = line.split(";");
                        ProgTyp progTyp = ProgTyp.fromCode(parts[3]);
                        TEintrag eintrag = new TEintrag(
                                Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]),
                                progTyp, parts[4], parts[5],
                                Integer.parseInt(parts[6]), Integer.parseInt(parts[7]), Integer.parseInt(parts[8]));
                        if (!progTyp.equals(ProgTyp.DIVERSE))
                            gesamt.add(eintrag);
                    } catch (Exception e) {
                        System.out.println("Fehler beim Einlesen der Zeile: " + line);
                    }
                });
            } catch (IOException e) {
                System.out.println("Fehler beim Lesen der Datei: " + e.getMessage());
            }
        }
    }

    public static void main(String[] args) {
        TMenueManager menueManager = new TMenueManager();
        menueManager.loadCSV("daten.csv");
        menueManager.fuehreMenueAus();
        System.out.println("Beenden");
    }
}

Wenn ihr noch Kommentare habt, oder Verbesserungsvorschläge oder meint, das könne man doch alles viel kürzer ausdrücken, dann laßt es mich bitte wissen. Ein paar {} die ich eigentlich entfernt hatte, hat mir die automatische Formatierung von Eclipse wieder reingehauen, sei's drum
 

Anhänge

  • freiburg-pascal.txt
    9,9 KB · Aufrufe: 0
  • freiburg-python.txt
    3,9 KB · Aufrufe: 0

Oneixee5

Top Contributor
Hier wird System.in automatisch geschlossen - normalerweise ist das keine gute Idee. Idealerweise sollte nur einen Scanner von System.in erstellt werden, der für die gesamte Lebensdauer des Programms verwendet wird.
Java:
try (Scanner scanner = new Scanner(System.in)) {
    ...
}

Eine Frage noch: Must du Zeilen sparen oder kosten die extra? Wie erklärst du so einen Code:
Java:
        TEintrag(int M1, int M2, int M3, ProgTyp progTyp, String BEZEICHNER, String CODE, int N1, int N2, int L1) {
          this.M1 = M1; this.M2 = M2; this.M3 = M3;
          this.progTyp = progTyp; this.BEZEICHNER = BEZEICHNER; this.CODE = CODE;
          this.N1 = N1; this.N2 = N2; this.L1 = L1;
        }
Ließ mal hier: https://google.github.io/styleguide/javaguide.html

void kopiereVon(final TEintrag quelle) - wird nirgends verwendet und wäre eher etwas für einen Copy-Constructor.

Die Verwendung von Stack: Stack<TEintrag> mStack = new Stack<>(); ist hier nicht notwendig. Stack ist synchronized, was hier einen unnötigen Overhead darstellt.

Enums vergleicht man nicht mit equals, sondern mit ==
Java:
if (ProgTyp.PROGRAMM.equals(punkt.progTyp)) {
    ...              
} else if (ProgTyp.MENUE.equals(punkt.progTyp)) {
    ...
}

Das ist ein Scherz oder?
Java:
                while (true) {
                    if (!this.menueAngezeigt) {
                        this.zeigeMenue();
                        this.menueAngezeigt = true;
                    }
                    ...
                }
 
Zuletzt bearbeitet:

alfware17

Aktives Mitglied
Hier wird System.in automatisch geschlossen - normalerweise ist das keine gute Idee. Idealerweise sollte nur einen Scanner von System.in erstellt werden, der für die gesamte Lebensdauer des Programms verwendet wird.
Java:
try (Scanner scanner = new Scanner(System.in)) {
    ...
}

Eine Frage noch: Must du Zeilen sparen oder kosten die extra? Wie erklärst du so einen Code:
Java:
        TEintrag(int M1, int M2, int M3, ProgTyp progTyp, String BEZEICHNER, String CODE, int N1, int N2, int L1) {
          this.M1 = M1; this.M2 = M2; this.M3 = M3;
          this.progTyp = progTyp; this.BEZEICHNER = BEZEICHNER; this.CODE = CODE;
          this.N1 = N1; this.N2 = N2; this.L1 = L1;
        }
Ließ mal hier: https://google.github.io/styleguide/javaguide.html

void kopiereVon(final TEintrag quelle) - wird nirgends verwendet und wäre eher etwas für einen Copy-Constructor.

Die Verwendung von Stack: Stack<TEintrag> mStack = new Stack<>(); ist hier nicht notwendig. Stack ist synchronized, was hier einen unnötigen Overhead darstellt.

Enums vergleicht man nicht mit equals, sondern mit ==
Java:
if (ProgTyp.PROGRAMM.equals(punkt.progTyp)) {
    ...             
} else if (ProgTyp.MENUE.equals(punkt.progTyp)) {
    ...
}

Das ist ein Scherz oder?
Java:
                while (true) {
                    if (!this.menueAngezeigt) {
                        this.zeigeMenue();
                        this.menueAngezeigt = true;
                    }
                    ...
                }

Hallo, vielen Dank für deine Hinweise.

Das mit dem Scanner habe ich nicht verstanden - wo sollte der denn hin? Um das ganze main? Eigentlich ist es ja nur eine Methode fuehre_menue_aus, die die ganze Zeit unterwegs ist?

TEintrag.kopieren() ist eine Altlast, das stimmt - wenn ich richtig sehe, wurde das in finde_menuepunkt mal gebraucht, wo der Eintrag noch in der Parameterliste war. Da existierte der Punkt also schon und ich konnte keinen Copy-Konstruktor nehmen, ich habe in der Tat lange daran gebastelt.
Nun gut, nun hat die Methode eben TEIntrag als Typ und damit ist es gelöscht. Das ist leider eine "Altlast" aus dem Pascal, wo solche komplexen
Methodentypen nicht möglich waren.

Die vielen kleinen Einträge auf einer Zeile mache ich nur, wenn sie so immer gleich sind und langweilig. 9 Parameter auf 9 einzelnen Zeilen war mir zu viel. Ich fand das dann künstlich aufgebläht. Aber gut wenn es die Konvention will. Sonst schreibe ich auch lieber breit und übersichtlich,
nur wie gesagt, ich wollte damit auch irgendwie ausdrücken, daß es nur eine langweilige Aufzählung ist.

Was genau ist an meiner while(true) Schleife verkehrt? Daß das break nur aus dem try herauskommt wenn das Menu "fertig" also Ende = true feststellt? Ich kann eine Variable ende einführen, so habe ich es glaube ich im Pascal auch.
Oder ist der "Schalter" menue_angezeigt das Problem. Den kann ich in der Tat verstecken.
if (!menue_angezeigt)
zeige_Menue()

Und das zeigeMenue() setzt dann den Schalter. Das ist besser, meintest du das?

Das mit dem Stack habe ich wieder nicht verstanden - was genau darf man weglassen, die Typisierung?

Danke nochmal für deine Hinweise, ich setze das alles auch immer noch um in der Eclipse
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Reader für Benutzereingabe in Eclipse importieren Java Basics - Anfänger-Themen 3
Haubitze_Broese Pattern für Links in RSS-Reader Java Basics - Anfänger-Themen 6
K Warum wird hier nur etwas in eine txt Datei geschrieben und nicht in alle drei (InputStream/OutputStream/Reader/Writer) Java Basics - Anfänger-Themen 1
R CSV Reader läuft nicht richtig an Java Basics - Anfänger-Themen 8
S Input/Output Reader/Writer finden file nicht Java Basics - Anfänger-Themen 3
L Klassen NFC Reader und JavaFx Problem -> threads? Java Basics - Anfänger-Themen 2
A Reader wohin werden Daten gespeichert? Java Basics - Anfänger-Themen 7
Textsurfer Erste Schritte CSV Import Reader Writer Java Basics - Anfänger-Themen 0
W Reader Java Basics - Anfänger-Themen 9
W Java XML-Reader: Content not allowed in Prolog Java Basics - Anfänger-Themen 7
D Jpg in BufferedImage Reader oder Array ablegen? Java Basics - Anfänger-Themen 5
H "Conways GameofLife - Vom Reader ins Array" Java Basics - Anfänger-Themen 5
C FileWriter bzw. Reader fehlerhaft Java Basics - Anfänger-Themen 6
Sogomn Input/Output Reader, Writer und Streams Java Basics - Anfänger-Themen 6
P txt reader Problem Java Basics - Anfänger-Themen 17
L buffered reader produziert zu viele und seltsame zeichen Java Basics - Anfänger-Themen 2
A Interface Reader interface verwenden Java Basics - Anfänger-Themen 4
S Input/Output Reader: "null" wenn While-Ende Java Basics - Anfänger-Themen 5
F Reader - brauche Hilfe Java Basics - Anfänger-Themen 19
M Reader-Problem Java Basics - Anfänger-Themen 5
Haubitze_Broese RSS-Reader? Java Basics - Anfänger-Themen 2
A Problem Reader Java Basics - Anfänger-Themen 39
Developer_X Sav-Data reader, fehler Java Basics - Anfänger-Themen 2
V Buffered Reader, erst ab bestimmter Zeile auslesen? Java Basics - Anfänger-Themen 8
K Probleme mit Buffered Reader Java Basics - Anfänger-Themen 8
P Buffered Reader an Anfang setzen Java Basics - Anfänger-Themen 4
D RSS Reader mit Redaktionssystem Java Basics - Anfänger-Themen 7
L Streams und Reader/Writer Java Basics - Anfänger-Themen 8
F Was gibt der Buffered Reader zurück bei Dateiende? Java Basics - Anfänger-Themen 2
T Writer/Reader Problem Java Basics - Anfänger-Themen 4
H Buffered Reader Java Basics - Anfänger-Themen 7
G Buffered REader, String, ist mein code korrekt? Java Basics - Anfänger-Themen 4
W Methoden java map ersatz für c++map Java Basics - Anfänger-Themen 2
S Bitte Ratschläge für Console-MenuFührung... Java Basics - Anfänger-Themen 20
tomzen Java Unterstützung für exel dateien installieren. Java Basics - Anfänger-Themen 2
M Code aus IntelliJ in "Textform" für Word-Paper? Java Basics - Anfänger-Themen 10
G Icon für App Java Basics - Anfänger-Themen 1
Kerstininer Vererbung Hilfe beim lernen von Objektorientierung für eine Klausur Java Basics - Anfänger-Themen 10
Sniper1000 Java 391 für Windows Java Basics - Anfänger-Themen 37
P Wieso kann ich als Index für einen Array einen Char angeben? Java Basics - Anfänger-Themen 3
benny1993 Java Programm erstellen für ein Fußball-Turnier Java Basics - Anfänger-Themen 3
V Durchschnittliche Volatility in Prozent für 4 Stunden berechnen Java Basics - Anfänger-Themen 14
P Welches SDK für das erstellen einer ausführbaren Datei? Java Basics - Anfänger-Themen 4
C negamax-Algorithmus für Tic-Tac-Toe spielt manchmal falsch Java Basics - Anfänger-Themen 10
D Apache HTTPClient für alle Fälle Java Basics - Anfänger-Themen 41
J Layout Manager, welcher ist der Richtige für mein Program? Java Basics - Anfänger-Themen 1
J Fehlermeldung unverständlich für Jakarta Java Basics - Anfänger-Themen 17
M Minimax-Algorithmus für Vier gewinnt Java Basics - Anfänger-Themen 11
M GUI für Vier-Gewinnt. Java Basics - Anfänger-Themen 4
I JPA Query für mehrere Klassen Java Basics - Anfänger-Themen 3
D Quellcode für cmd funktioniert nicht Java Basics - Anfänger-Themen 9
R Operatoren Rechenoperation in Java verwenden für Calculator Java Basics - Anfänger-Themen 2
R Operatoren Rechenoperation verwenden für Taschenrechner. Java Basics - Anfänger-Themen 32
Ostkreuz Counter für Booleanwerte Java Basics - Anfänger-Themen 8
B Regex Ausdrücke für Monate Java Basics - Anfänger-Themen 7
I BlueJ Queue Frage für Klausur Java Basics - Anfänger-Themen 2
K loop pausieren für eine bestimmte Anzahl? Java Basics - Anfänger-Themen 1
Jxhnny.lpz Randomisier für Buttons Java Basics - Anfänger-Themen 13
W Intuitive interface für Komponenten Java Basics - Anfänger-Themen 4
M "Class<T> clazz" im Constructor - auch für int möglich? Java Basics - Anfänger-Themen 7
B Schrankensystem mit Farberkennung für Flashgame funktioniert nicht wie geplant Java Basics - Anfänger-Themen 4
I Code für Bezahlsystem (auch bei Offline Aktivität) Java Basics - Anfänger-Themen 7
U jUnit 5 Test für eine addMethode Java Basics - Anfänger-Themen 18
M monte carlo Algorithmus für 4 gewinnt Java Basics - Anfänger-Themen 12
frager2345 Java Singleton Muster -> Methode für Konstruktor mit Parametern Java Basics - Anfänger-Themen 3
izoards Sortier Algorithmus für Bounding Box Elememte Links nach Rechts und von Oben nach Unten Java Basics - Anfänger-Themen 33
M generate Methode für Streams Java Basics - Anfänger-Themen 6
I Datenmodell für "Tags" Java Basics - Anfänger-Themen 6
Lion.King for-Kontrollstruktur für Pyramide Java Basics - Anfänger-Themen 8
B Mit Countdown Midnestdauer für Teilaufgabenerledigung erzwingen Java Basics - Anfänger-Themen 8
J File length als Prüfwert für Download Java Basics - Anfänger-Themen 5
K Spieleidee gesucht für Informatikprojekt - JAVA (BlueJ)? Java Basics - Anfänger-Themen 15
P Zähler Variable für mehrere Objekte Java Basics - Anfänger-Themen 6
javamanoman Java für Online Banking Java Basics - Anfänger-Themen 12
NadimArazi Wie kann ich eine collision detection für die Paddles in meinem Pong Programm hinzufügen? Java Basics - Anfänger-Themen 4
JordenJost Java ist auch eine Insel für Anfänger Java Basics - Anfänger-Themen 2
P9cman Tipps für Rekursive Aufgaben mit Strings oder allgemein Java Basics - Anfänger-Themen 2
F Suche nach betreuender Person für eine Jahresarbeit der 12. Klasse. Java Basics - Anfänger-Themen 6
I SQL / JPA Query für StartDate und EndDate Java Basics - Anfänger-Themen 1
T getMethode für ein Array Java Basics - Anfänger-Themen 2
Fats Waller Farben mixen für den Hintergrund ? Java Basics - Anfänger-Themen 1
H Suche jemanden für kleine Uni-Abgabe/ mit Vergütung Java Basics - Anfänger-Themen 1
K Für was braucht man die left und right shift operatoren? Was bringen die, also welchen Zweck haben die? Java Basics - Anfänger-Themen 15
N Api nur für Textdatein (.txt) Java Basics - Anfänger-Themen 2
bluetrix Programmieren eines Bots für Zahlen-Brettspiel Java Basics - Anfänger-Themen 9
M Wie kann eine Methode für ein vorhandenes "Array von char" einen Index-Wert zurückliefern? Java Basics - Anfänger-Themen 3
R Ist Java das Richtige für mich? Java Basics - Anfänger-Themen 4
E Mittelquadratmethode für Hexadezimalzahlen Java Basics - Anfänger-Themen 1
P Einfacher regulärer Ausdruck (RegEx) für E-Mail-Adressen Java Basics - Anfänger-Themen 2
Kiki01 Wie würde eine geeignete Schleife aussehen, die die relative Häufigkeit für jeden Charakter in einem Text bestimmt? Java Basics - Anfänger-Themen 3
N Fehler im Code (Aufgabe für Anfänger) Java Basics - Anfänger-Themen 11
O Wie erstelle ich eine Instanz in einer Klasse für die ich die Instanz will? Java Basics - Anfänger-Themen 4
S BubbleSort für ArrayLists Java Basics - Anfänger-Themen 3
T Übungsbuch für Anfänger Java Basics - Anfänger-Themen 3
L Konzept für Quiz Java Basics - Anfänger-Themen 33
D Methoden Plathhalter für Integer in einer Methode Java Basics - Anfänger-Themen 19
B Datentyp für Einzelnes Objekt oder Liste Java Basics - Anfänger-Themen 9
D Welche GUI Library für eine Client Server Chat App Java Basics - Anfänger-Themen 14
T Algorithmus für Index mit min-Wert Java Basics - Anfänger-Themen 2
Aqtox Hallo ich muss für die Schule ein Wuerfell Duell erstellen jedoch habe ich ein fehler Java Basics - Anfänger-Themen 4

Ähnliche Java Themen


Oben