HARALD MELCHER

Startrek in C

Verbesserter Parser

Im bisherigen Code tauchen Abschnitte mehrfach auf – das sind Verbesserungsmöglichkeiten. Gerade die Anweisungen zum

  • Ausgeben eines Fragetextes (ohne Linefeed)
  • Flushen des Ausgabebuffers (der sonst nur bei Linefeed geflusht wird)
  • Einlesen der Antwort der Spielerin
  • Entfernen des schließenden Linefeeds

tauchen mehrfach auf. Lagere sie in eine Funktion void ask(char* question, char* buffer, int bufsize) aus!

Die Funktion parse_command(char* cmd) überprüft bislang alle Möglichkeiten in getrennten if-Anweisungen. Dies ersetzt du durch eine Tabelle mit Kommandonamen und den passenden enums. Damit kannst du auch einfach mehrere unterschiedliche Bezeichnungen für das gleiche Kommando einführen.

Außerdem wird der Code dann das Kommando nur auf soviele Buchstaben vergleichen, wie die Benutzereingabe lang ist.

Zunächst wird eine kleine Hilffunktion int command_length(char *cmd) die Länge des Kommandos ermitteln, indem sie die Zeichen bis zum ersten Leerzeichen, Zeilenende oder Stringende zählt.

Ein typedef für den Typ command_list_entry beschreibt einen einzelnen Eintrag in der Kommandoliste, die ein Array command_list dieser Einträge ist.

typedef struct {
    char* command;
    int command_code;
} command_list_entry ;

In den Initialisierer des (globalen) command_list-Array kommen jetzt Paare aus Kommandos und den dazu passenden enums.

command_list_entry command_list[] = {
        {"exit", exit},
        {"help", help},
        {"srs", short_range_scan},
        {"lrs", long_range_scan}
};

Die Funktion parse_command(char* cmd) muss jetzt nur noch alle Einträge im command_list-Array durchgehen (s.u.) und einen Stringvergleich (mit Längenangabe aus dem Kommando) durchführen. Passt der Vergleich, liefert sie die dazugehörige enum zurück. Passt keiner der Strings, liefert sie das enum für unbekannt zurück.

Die Zahl der Einträge in einem Array errechnet sich aus der Größe des Arrays geteilt durch die Größe eines Array-Eintrags (also beispielsweise des ersten).

int num_entries = sizeof(command_list) / sizeof(command_list[0]);

Jetzt kannst du neue Einträge in die Kommandoliste einbauen, zum Beispiel “quit” als Alternative zu Exit.