2013-02-14 12 views
6

Ich habe versucht, reguläre Ausdrücke auf scanf zu verwenden, um eine Zeichenfolge mit maximal n Zeichen zu lesen und alles andere bis zum neuen Zeilenzeichen zu verwerfen. Alle Leerzeichen sollten als reguläre Zeichen behandelt und somit in die zu lesende Zeichenfolge eingeschlossen werden. Ich habe einen Wikipedia-Artikel über Reguläre Ausdrücke studiert, aber ich kann scanf nicht richtig funktionieren. Hier ist ein Code ich habe versucht:Verwenden Sie scanf mit regulären Ausdrücken

scanf("[ ]*%ns[ ]*[\n]", string); 

[] soll für den eigentlichen Raumzeichen gehen, wird * soll ein oder mehrere bedeuten, n die Anzahl der zu lesenden Zeichen und String ist ein Zeiger zugewiesen mit malloc. Ich habe verschiedene Kombinationen ausprobiert; aber ich neige dazu, nur das erste Wort eines gelesenen Satzes zu erhalten (stoppt bei Leerzeichen). Darüber hinaus scheint * ein Zeichen zu verwerfen anstatt "null oder mehr" zu bedeuten ...

Kann jemand im Detail erklären, wie reguläre Ausdrücke von scanf interpretiert werden? Was ist mehr, ist es effizient, getc wiederholt zu verwenden?

Vielen Dank im Voraus: D

+2

Versuchen Sie 'fgets()': 'fgets (string, sizeof string, stdin);' – pmg

+0

Das Problem ist, dass alle verbleibenden Zeichen im Eingabestream verbleiben, nicht wahr? – someone

+0

Wenn genug Platz ist, 'fgets()' verbraucht alles bis zu (und inklusive) ein ''\ n''. – pmg

Antwort

4

Die kurze Antwort: scanf behandelt nicht reguläre Ausdrücke wahrsten Sinne des Wortes.

Wenn Sie reguläre Ausdrücke in C verwenden möchten, können Sie die regex POSIX-Bibliothek verwenden. Sehen Sie sich die folgende Frage zum Grunde Beispiel auf dieser Bibliothek Nutzung: Regular expressions in C: examples?

Nun, wenn Sie es den scanf Weg machen wollen Sie so etwas wie

scanf("%*[ ]%ns%*[ ]\n",str); 

Ersetzen Sie die n in %ns durch die maximale Zahl versuchen könnten von Zeichen, die aus dem Eingabestream gelesen werden sollen. Der %*[ ] Teil fordert alle Leerzeichen zu ignorieren. Sie können die * durch eine bestimmte Zahl ersetzen, um eine genaue Anzahl von Zeichen zu ignorieren. Sie können andere Zeichen zwischen geschweiften Klammern hinzufügen, um mehr als nur Leerzeichen zu ignorieren.

Nicht sicher, ob das obige scanf funktionieren würde, da Leerzeichen auch mit der %s Direktive übereinstimmen.
würde ich mit einem fgets Anruf auf jeden Fall, dann die umliegenden Whitespaces mit so etwas wie die folgenden triming: How do I trim leading/trailing whitespace in a standard way?

+0

Also, schließlich gibt es keine andere Möglichkeit, irgendwelche zu verwerfen verbleibende Eingabe? Ich habe darüber nachgedacht, getc wiederholt zu verwenden, die Anzahl der Zeichen zu behalten, die ich brauche, und den Rest der Zeichenfolge zu verwerfen, bis das \ n Zeichen gefunden wird ... – someone

+0

Ich habe meine Antwort zur gleichen Zeit bearbeitet, als du deinen Kommentar gepostet hast. Es ist also möglich, einige Eingaben zu ignorieren, aber ich würde die scanf-Formatzeichenfolge nicht als "regulären Ausdruck" bezeichnen. – greydet

+0

Danke für Ihre Antwort! Kannst du jedoch die Semantik erklären, was du dort benutzt hast? – someone

2

ist es effizient wiederholt statt getc zu benutzen?

hängt etwas von der Anwendung, aber JA, wiederholte getc() effizient ist.

0

Wenn ich die Frage nicht falsch gelesen habe, speichert% [^ '\ n'] s alles, bis der Wagenrücklauf angetroffen wird.

+1

Das 's' in'% [^ '\ n'] s wird nicht benötigt. – chux

Verwandte Themen