2017-07-14 3 views
3

Für eine Befehlszeilenanwendung muss ich die Eingabezeichenfolge mit einem Befehlsmuster vergleichen. Leerzeichen müssen ignoriert werden.Vergleichen Sie Zeichenfolgen mit sscanf, aber ignorieren Sie Leerzeichen

Diese Zeile sollte Eingabezeichenfolgen wie „fallen alle“ und „fallen alle“ entsprechen: hier

int rc = sscanf(input, "drop all"); 

Was aber zeigen ein erfolgreiches Spiel?

+2

Sie scheinen ein falsches Werkzeug für den Job gewählt zu haben ... –

+0

@EugeneSh. vielleicht, aber einige Befehle nehmen auch Zahlen usw. als Argumente. Das ist also ein Spezialfall ohne Argumente. – mwarning

Antwort

5

Verwenden Sie "%n", um aufzuzeichnen, wo der Scan gestoppt wurde.

Fügen Sie Leerzeichen in dem Format hinzu, in dem WS in input ignoriert werden muss.

int n = -1; 
sscanf(input, " drop all %n", &n); 
// v---- Did scanning reach the end of the format? 
// |   v---- Was there additional text in `input`? 
if (n >= 0 && input[n] == '\0') Success(); 
+2

Ehrlich gesagt, würde ich nicht verstehen, was dieser Code tut, ohne die Anforderung in der Frage gegeben. –

+0

Funktioniert das mit 'drop all' und' drop all'? (Kommentare Parser scheint kaputt zu sein ...) – VTT

+0

@VTT: Warum versuchst du es nicht? Es ist nicht schwer zu tippen und Copy'n'Paste macht es noch einfacher. Die Leerzeichen in der Formatzeichenkette entsprechen 0 oder mehr Leerzeichen, z. B. Leerzeichen, Tabulatoren, Zeilenumbrüche. Und Markdown macht es schwierig, mit Back-Ticks und Leerzeichen (oder anderen Back-Ticks) das gewünschte Ergebnis zu erhalten. –

1

Anstatt mit schmutzigen Daten zu arbeiten, ist es oft besser, sie zu bereinigen und dann damit zu arbeiten. Die Bereinigung muss nur einmal durchgeführt werden, während schmutzige Daten jedes Mal, wenn Sie sie verwenden müssen, die Komplexität des Codes erhöhen. Dieser Schritt wird oft als "Normalisierung" bezeichnet. Normalisieren Sie die Eingabe in eine kanonische Form, bevor Sie sie verwenden.

Bereinigen Sie die Eingabe, indem Sie Whitespace trimmen und eine andere Normalisierung durchführen (z. B. Falten und Normalisieren des internen Leerraums).

Sie könnten Ihre eigene Trim-Funktion schreiben, aber ich würde Ihnen empfehlen, eine bereits existierende Funktion wie Gnome Lib's g_strstrip() zu verwenden. Gnome Lib bringt viele nützliche Funktionen mit.

#include <glib.h> 

void normalize_cmd(char *str) { 
    g_strstrip(str); 

    // Any other normalization you might want to do, like 
    // folding multiple spaces or changing a hard tab to 
    // a space. 
} 

Dann können Sie strcmp auf dem normalisierten Eingang verwenden.

// This isn't strictly necessary, but it's nice to keep a copy 
// of the original around for error messages and such. 
char *cmd = g_strdup(input); 

normalize_cmd(cmd); 

if (strcmp(cmd, "drop all") == 0) { 
    puts("yes"); 
} 
else { 
    puts("no"); 
} 

Wenn man die gesamte Normalisierung in den Vordergrund stellt, reduziert sich die Komplexität des gesamten nachgelagerten Codes, der mit diesem Eingang arbeiten muss; Sie müssen nicht dieselben Bedenken bezüglich schmutziger Daten wiederholen. Indem Sie die gesamte Normalisierung an einer Stelle platzieren und nicht über den gesamten Code verstreut sind, sind Sie sicher, dass sie konsistent ist und die Normalisierungsmethode konsistent aktualisiert werden kann.

+0

'strcmp (" drop \ tall "," drop all ")' wird nicht übereinstimmen. Typischerweise umfassen solche "Aufräumarbeiten" einen Durchlauf, um mehrere Leerzeichen in ein einziges "" zu konvertieren. – chux

+0

@chux Sicher. Führen Sie zusätzliche Bereinigungen und Normalisierungen durch, bevor Sie mit den Daten arbeiten. – Schwern

+0

Es ist ein zweischneidiges Schwert. Die vorgeschlagene Bereinigung eignet sich gut für die nachfolgende Verarbeitung. Die ursprüngliche Eingabe ist jedoch nützlich für die Protokollierung und das Debugging. Wie bei jeder Benutzereingabe ist es böse und sollte nicht verwendet werden, bis überprüft. – chux

Verwandte Themen