Input/Output Befehl aus Benutzereingabe herausfiltern

DagobertDuck

Bekanntes Mitglied
Guten Abend,

ich versuche mir seit Tagen einen ordentlichen Command-Handler zu basteln. Es scheitert leider immer daran, dass ich zwischen Befehlen unterscheiden muss, die ein, zwei oder drei Wörter lang sind.

Hier ist mein derzeitiger Code bei dem ich nicht weiter komme:
Java:
        register = new Register();
        CommandParser parser = new CommandParser(this);
        while (running) {
            String input = Terminal.readLine();
            try {
                final List<Command> commands = parser.initialiseCommands(register);
                final List<String> inputSplit = Arrays.asList(input.split(" "));
                final Command command = commands.stream()
                        .filter(cmd -> cmd.getName().equals(???)
                        .findAny()
                        .orElseThrow(() -> new InvalidInputException("no such command");
                final List<String> arguments = parser.getArguments(inputSplit, command);
                command.setArguments(arguments);
                command.execute();
            } catch (InvalidInputException | BadSyntaxException e) {
                Terminal.printError(e.getMessage());
            }
        }


und hier ist meine getArguments() Methode:

Java:
    public List<String> getArguments(final List<String> inputSplit, final Command command) throws BadSyntaxException {
        int commandCount = command.getName().split(" ").length;
        final List<String> arguments = inputSplit.subList(commandCount, inputSplit.size());
        if (arguments.size() != command.getNumberOfArguments()) {
            throw new BadSyntaxException("invalid number of arguments. Expected %d arguments",
                    command.getNumberOfArguments());
        }
        return arguments;
    }

initialiseCommands() enthält alle registrierten Befehle (jeder Befehl ist in einer eigenen Klasse). Des Weiteren verfügt jeder Befehl über die Methode getName(), die eine Zeichenkette des Befehlsnamens zurückgibt (z. B. für den Befehl add track <point> -> <point> ist es "add track").

Hier sind ein paar Befehle mit unterschiedlicher Wortlänge des Befehlsnamens:
- add track <point> -> <point> - Länge 2
- exit - Länge 1
- delete rolling stock <id> - Länge 3

Wie kann ich jetzt gescheit die Eingaben von Benutzer parsen und den potenziell richtig eingegeben Befehl rausfiltern?

Beispiel:
add track (1,2) -> (3,2) -> Command command = AddTrackCommand().
Sobald ich den Befehl habe, bekomme ich die Argumente automatisch mit meiner getArguments() Methode. Es geht also wirklich nur darum, den Befehl zu filtern, den der Benutzer eingibt.

Falls irgendetwas unklar sein sollte, fragt bitte nach. Ich mache mir seit Tagen Gedanken um dieses scheinbar unlösbare Problem...
 

DagobertDuck

Bekanntes Mitglied
Seitdem habe ich so viele andere Alternativen versucht, dass ich das schon alles gar nicht mehr im Kopf habe.

Ein Problem war aber, dass z. B. auch "exit 42" angenommen wird, obwohl nur "exit" angenommen werden sollte. "exit 42" -> "unknown command".
 

DagobertDuck

Bekanntes Mitglied
@mihe7 Eventuell ist das ja sogar gar nicht so schwierig das zu beheben? Dann würde ich es noch mal mit deiner Variante versuchen und falls weitere Probleme aufkommen sollten, melde ich mich erneut.
 

DagobertDuck

Bekanntes Mitglied
Außerdem verstehe ich deine Klassenaufteilung auch noch nicht so ganz.

Ich würde gerne eine Klasse CommandParser, in der die Befehle registriert werden und eine Main Klasse, in der die Befehle durch die Eingabe ausgeführt werden, haben.

Egal wie ich es versuche, ich schaffe es nicht deine Implementierung darauf anzupassen. Wenn ich das nicht tue, passt das alles mit meinem Register und der Session nicht.
 

Mika34

Bekanntes Mitglied
Ich habe momentan für jede valide Eingabe einen Regex, welcher gecheckt wird, ob die Eingabe diesem entspricht.
Jedoch bin ich mir nicht sicher, ob dies nicht unter Hard-Codierung fällt und und zum anderen ist dies doch bestimmt schlechter Stil, wenn man für jede potentielle Eingabe einen regulären Ausdruck definiert, oder nicht?
Denn, wenn eine Eingabe nicht in das Muster fällt, soll das Programm beendet werden, aber wenn es passt, soll es einfach weiterlaufen...
Was meint ihr dazu
 

mihe7

Top Contributor
Ich verstehe Euer Problem nicht: eine Befehlszeile besteht einfach aus mehreren Zeichenketten, nennen wir sie mal Tokens, die durch Whitespace voneinander getrennt sind: <token> <token> <token>...

Die Liste der Tokens erhält man also über:
Java:
List<String> getTokens(String commandLine) {
    return Arrays.asList(commandLine.split("\\s"));
}

Jetzt ist die Frage, wie man die Tokens interpretiert. Da man zwischen verschiedenen Befehlen unterscheiden können muss, gibt das erste Token den Befehl (bzw. den ersten Teil eines Befehls) an. D. h. um einen Befehl zu bestimmen, hat man einen Entscheidungsbaum der Form:
Code:
          Start
            |
  +---------+----------+
  |         |          |
  v         v          v
 exit      step      delete
                       |
                       +--------+
                       |        |
                       v        v
                     rolling   track
                       |         
                       v         
                     stock

Das kann man nun auf unterschiedliche Weise implementieren. Eine Möglichkeit besteht darin, den Baum einfach als Objektgraph umzusetzen. Dazu betrachtet man einen Command als Befehl, der zur Ausführung eine Tokenliste erhält (s. https://www.java-forum.org/thema/im...sers-fuer-viele-eingaben.187285/#post-1211057)

Der erste Befehl (dessen Name uninteressant ist) erhält also alle Tokens und wählt nun anhand des ersten Tokens den nächsten Befehl aus. Dieser erhält zur Ausführung nur noch den Rest der Liste als Argument.

Also:
Befehlerhält ArgumenteAktion
Start-Befehl"delete", "rolling", "stock", "<id>"wählt delete-Befehl aus und übergibt die verbleibenden Argumente
delete"rolling", "stock", "<id>"wählt rolling-Befehl aus und übergibt die verbleibenden Argumente
rolling"stock", "<id>"wählt stock-Befehl aus und übergibt die verbleibenden Argumente
stock"<id>"Führt den Befehle "delete rolling stock" aus.

Das ergibt dann Code ähnlich zu dem im genannten Link. Programmiert man noch ein Fluent Interface, dann ließe sich der Baum oben z. B. darstellen mit:

Java:
DefaultCommand root = new DefaultCommand()
    .register("exit", args -> System.exit(0))
    .register("step", new StepCommand(...))
    .register("delete", new DefaultCommand()
        .register("rolling", new DefaultCommand()
            .register("stock", new DeleteRollingStockCommand(...))
        )
    );
Die Pünktchen als Platzhalter sollen anzeigen, dass die Befehle ggf. mit weiteren Objekten zusammenarbeiten müssen, die an der Stelle übergeben werden können.

Ausgeführt wird dann eine Befehlszeile durch
Java:
root.execute(getTokens(commandLine));
 

Mika34

Bekanntes Mitglied
Hier wird dann aber gar nicht geprüft, ob es eine valide Eingabe war oder nicht. Das irritiert mich gerade noch sehr oder wird geprüft und ich verstehe es nur nicht
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
X wie bekomme ich durch Eingabeaufforderung definierte double in einen Befehl, welcher 3 erwartete double braucht? Java Basics - Anfänger-Themen 3
J jar Befehl wird nicht erkannt Java Basics - Anfänger-Themen 7
Viktor A. Kaiser Ampelschaltung mit if-Befehl Java Basics - Anfänger-Themen 11
Fodoboo131 RegEx- Umwandlung von String in ausführbares Objekt/ Befehl Java Basics - Anfänger-Themen 9
Lion.King switch-Befehl Java Basics - Anfänger-Themen 6
sserio Math. Befehl wird rot markiert Java Basics - Anfänger-Themen 5
F Terminal Windows per Befehl schließen? Java Basics - Anfänger-Themen 9
Y Wie kann man überprüfen, ob bei einem Print Befehl tatsächlich etwas geprintet wurde? Java Basics - Anfänger-Themen 4
H Befehl wird nicht ausgeführt - System.out.println Java Basics - Anfänger-Themen 3
A Scanner Befehl Java Anfänger Java Basics - Anfänger-Themen 8
K Subklassen mit einzigem Befehl addieren Java Basics - Anfänger-Themen 6
F cmd Befehl ausführen Java Basics - Anfänger-Themen 4
S Datenbank Befehl nach Login Java Basics - Anfänger-Themen 5
T if else Befehl funktioniert nicht richtig Java Basics - Anfänger-Themen 27
N Javac -version der Befehl ist entweder falsch geschrieben oder...... Java Basics - Anfänger-Themen 8
O Methoden Runtime.getRuntime().exec(befehl); Java Basics - Anfänger-Themen 6
L Ist an diesem Befehl irgendwas falsch? Java Basics - Anfänger-Themen 2
F Wieso wird dieser Befehl nicht ausgeführt? (Anfänger) Java Basics - Anfänger-Themen 2
B Copy Paste Befehl Java Basics - Anfänger-Themen 6
O String: Befehl und Wert erkennen. Java Basics - Anfänger-Themen 4
D Erste Schritte Zuul - 2ten Befehl einführen Java Basics - Anfänger-Themen 68
D Erste Schritte Befehl back implementieren Java Basics - Anfänger-Themen 18
elischa unbekannter Befehl zur Compilezeit Java Basics - Anfänger-Themen 22
B Befehl um ein Befehl abzubrechen Java Basics - Anfänger-Themen 2
M Classpath Befehl zum Kompilieren um die Option classpath erweitern. Java Basics - Anfänger-Themen 5
F Konsolen Befehl ausführen und Rückgabe auswerten Java Basics - Anfänger-Themen 3
S Befehl current: Java Basics - Anfänger-Themen 3
Silvascus Void Methode einem Stringparameter im syso-Befehl hinzufügen Java Basics - Anfänger-Themen 3
slejden Erste Schritte der Befehl import Java Basics - Anfänger-Themen 2
C OOP array Sortieren ohne den sort Befehl Java Basics - Anfänger-Themen 10
J Problem WIE ohne Goto-Befehl lösbar? Java Basics - Anfänger-Themen 6
N Benötige eine Alternative für einen GOTO Befehl Java Basics - Anfänger-Themen 2
O CMD Befehl javac Java Basics - Anfänger-Themen 3
U Java Swing Timer mit ButtonKlick starten u. nach 12 Sekunden Befehl ausführen Java Basics - Anfänger-Themen 7
D Klassenmethode: Befehl erkennen, dann int zurückgeben Java Basics - Anfänger-Themen 2
C Desktopiconwechsel ohne Befehl Java Basics - Anfänger-Themen 0
V Schlüsselworte Befehl Ignorieren? Java Basics - Anfänger-Themen 10
B JDK installieren Befehl java funktioniert nicht Java Basics - Anfänger-Themen 15
J Variablen Auf der suche nach einem Befehl Java Basics - Anfänger-Themen 2
M Frage zum return; Befehl Java Basics - Anfänger-Themen 1
C CMD Befehl + Variable im Java-Code ausführen Java Basics - Anfänger-Themen 8
S Methoden auf befehl ausführen Java Basics - Anfänger-Themen 7
iB0T Eine Art Goto Befehl! Java Basics - Anfänger-Themen 27
H Exit Befehl in eigener Konsole Java Basics - Anfänger-Themen 9
D Erste Schritte bash-Befehl mit Swing ausführen Java Basics - Anfänger-Themen 8
A Schlüsselworte Befehl this Java Basics - Anfänger-Themen 8
E CMD Befehl über Java ausführen? Java Basics - Anfänger-Themen 4
E Warum wird Methode nicht durch return-Befehl beendet? Java Basics - Anfänger-Themen 3
D Hilfe zu Java Befehl In.open Java Basics - Anfänger-Themen 2
B Javadoc-Befehl unter Ubuntu Java Basics - Anfänger-Themen 2
I Befehl/Methode "los()" Java Basics - Anfänger-Themen 17
A Befehl gesucht....wie komme ich an Folgendes Objekt? Java Basics - Anfänger-Themen 6
I Return Befehl in Methode Java Basics - Anfänger-Themen 13
K Befehl per Shell an Java-Applet JAR übergeben Java Basics - Anfänger-Themen 16
S javac Befehl Java Basics - Anfänger-Themen 7
C Befehl zum Verlassen einer Schleife Java Basics - Anfänger-Themen 27
W Befehl ausführen bei Mausklick + gedrückte Strg-Taste Java Basics - Anfänger-Themen 2
B Befehl mit Priorität aufrufen Java Basics - Anfänger-Themen 4
I Befehl wird erst nach dem Ausführen einer Funktion ausgeführt Java Basics - Anfänger-Themen 4
K Problem mit h2 DB Insert Befehl Java Basics - Anfänger-Themen 6
B Befehl für vorselektierten Radiobutton Java Basics - Anfänger-Themen 2
H if-Befehl mit Buttongroup Java Basics - Anfänger-Themen 9
B assert befehl in netbeans Java Basics - Anfänger-Themen 3
M Objekto.Programm. Return-Befehl Java Basics - Anfänger-Themen 4
F Kann String in Befehl wandeln? Java Basics - Anfänger-Themen 12
F Simpler DrawLine - Befehl!? Java Basics - Anfänger-Themen 9
M Befehl zum Einlesen von Benutzereingaben Java Basics - Anfänger-Themen 1
M Befehl zum Fenster schließen? GUI Java Basics - Anfänger-Themen 3
L Do while Befehl verkürzen? Java Basics - Anfänger-Themen 16
-horn- Befehl an CMD übergeben Java Basics - Anfänger-Themen 15
A [Fehlermeldung]Sleep-Befehl Java Basics - Anfänger-Themen 4
B Befehl "javac" wird nicht erkannt Java Basics - Anfänger-Themen 14
S Befehl "javac" funktioniert und Windows 7 nicht? Java Basics - Anfänger-Themen 3
K Terminal Befehl mit Java unter Mac ausführen Java Basics - Anfänger-Themen 18
L Java Persistence API - Update Befehl? Java Basics - Anfänger-Themen 5
X Befehl import Java Basics - Anfänger-Themen 21
Antoras Explizite Typenumwandlung in einem Befehl Java Basics - Anfänger-Themen 3
A Button einen Befehl zuordnen Java Basics - Anfänger-Themen 7
N suche Datums befehl Java Basics - Anfänger-Themen 8
H Problem mit Tastatur Befehl Java Basics - Anfänger-Themen 11
J Kill befehl Java Basics - Anfänger-Themen 44
G java shell script starten und befehl übergeben Java Basics - Anfänger-Themen 3
Z Ant java -classpath befehl Java Basics - Anfänger-Themen 2
X JOptionPane.showMessageDialog(); - Import Befehl? Java Basics - Anfänger-Themen 4
K Befehl um am Anfang einer Methode zu kommen? Java Basics - Anfänger-Themen 9
G Befehl für Ende bei Switch-Auswahl Java Basics - Anfänger-Themen 11
K fehler mit der Befehl Console Java Basics - Anfänger-Themen 3
H Befehl mit Konstruktoren Java Basics - Anfänger-Themen 2
L Leider klappt bei mir ein Befehl nicht Java Basics - Anfänger-Themen 4
P Befehl zum einrücken der textausgabe? Java Basics - Anfänger-Themen 6
A Befehl ausführen beim Schließen der Konsole Java Basics - Anfänger-Themen 3
S Gibt es einen Befehl "Mausklick" o.ä? Java Basics - Anfänger-Themen 6
S Java-Programm ohne -jar Befehl? Java Basics - Anfänger-Themen 9
K Auf File- Befehl warten. Java Basics - Anfänger-Themen 10
T JDK installiert aber der Befehl "javac" funktionie Java Basics - Anfänger-Themen 5
B ItemListener - setText Befehl geht nicht Java Basics - Anfänger-Themen 3
I JNLP - Datenstrom auslesen, Werte berechnen, Befehl automati Java Basics - Anfänger-Themen 6
R auf button klick befehl ausführen Java Basics - Anfänger-Themen 11
G Jar Befehl wird von DOS nicht erkannt Java Basics - Anfänger-Themen 24
G Unix Befehl ps unter Java Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben