2016-11-15 5 views
1

Kann jemand erklären, wie das funktioniert? Ich weiß, dass es eine Zeichenfolge (mit Leerzeichen) liest, aber ich verstehe den Mechanismus dahinter nicht wirklich. Kann mir jemand Stück für Stück erklären?Details zum Lesen von Strings in C?

scanf("%[^\n]%*c",string); 
+0

Haben Sie versucht, die Manpage zu lesen? Wenn Sie auf einem Unix-System sind, geben Sie 'man scanf' ein und lesen Sie es durch. – EdgeCaseBerg

+0

Insbesondere weist das abschließende '% * c' an, den abschließenden' newline' als 'char' zu lesen und das Ergebnis zu verwerfen, um die' newline' im Eingabepuffer nicht zu belassen. –

+0

Hier ist eine gute Referenz von Regex: http://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean –

Antwort

2

Aus der Manpage:

Alle Konvertierungen von den% (Prozentzeichen) eingeführt Charakter

Eine Umwandlung ist, wie wir bestimmten Text-Strings entsprechen. Ein %s entspricht beispielsweise einem String, und %d entspricht einer dezimalen Ganzzahl. So bei der Zeichenfolge suchen, haben wir eine "%[ Umwandlung, die auf der Manpage nach:

[Spiele eine nicht leere Folge von Zeichen aus der angegebenen Liste der zulässigen Zeichen; ... die Menge wird durch die Zeichen zwischen dem offenen Klammerzeichen [Zeichen und einer geschlossenen Klammer] definiert.

Diese Konvertierung wird also eine Liste von Zeichen definieren, die angepasst und in Ihre Zeichenfolge eingelesen werden. Wichtig ist:

Die Menge schließt diese Zeichen aus, wenn das erste Zeichen nach der offenen Klammer ein Zirkumflex^ist.

Und wenn man sich die Zeichenfolge aussehen "%[^\n]%*c" Sie %[^\n] haben, was bedeutet, dass Sie alle Zeichen sind passend, bis ein Zeilenende-Marke getroffen.

Als nächstes haben Sie eine %* der Stern ist eine Umwandlung, die ignoriert was passt danach.Von der Manpage:

Unterdrückt die Zuweisung. Die folgende Konvertierung erfolgt wie üblich, aber es wird kein Zeiger verwendet. Das Ergebnis der Konvertierung wird einfach verworfen.

Also, wenn Sie in Ihrem letzten Spiel aussehen, haben Sie eine c, bekam

c Findet eine Folge von Breite count Zeichen (default 1);

so bedeutet das, dass Sie %*c 1 Zeichen zu gehen, und entsorgen Sie sie dann (das Zeichen angepasst wird, ist das Newline - was die %[^\n] nicht verbrauchen, weil Sie alles abgestimmt bis zu die Newline), wird es nicht in Ihrer string Variable gespeichert.

Das Lesen der Manpage ist dein Freund. Ich hoffe das hilft.

+0

Danke. Das hat mir wirklich geholfen. Ich schätze Ihre Hilfe. –

+1

Sie sollten auch auf den potenziellen Pufferüberlauf hinweisen, da die maximale Größe nicht angegeben ist. – chqrlie

+1

Und wenn das erste Zeichen ein "\ n" ist, ''% * c "' nicht passiert, '\ n'' bleibt in' stdin' und 'string' ist ein unbekanntes Zeichen. – chux

3
scanf("%[^\n]%*c",string); 

Dieses sagt, dass „alles, was bis zu einem Newline-Zeichen lesen und lesen dann ein Zeichen“. * (in %*c) soll die Zuordnung unterdrücken. Das ist es liest eine Zeile und verbraucht das Newline-Zeichen.

Von scanf():

Ein optionalen '*' zuzuweisungsUnterdrückungsZeichen: Scanf() liest Eingabe, wie durch die Umwandlungsspezifikation gerichtet, sondern verwirft die Eingabe. Es ist kein entsprechendes Zeigerargument erforderlich, und diese Spezifikation ist nicht in der Anzahl der erfolgreichen Zuweisungen enthalten von scanf() zurückgegeben.

Aber ich würde, zum Lesen von Zeilen, stattdessen fgets() verwenden und den abschließenden Zeilenumbruch danach konsumieren.

char string[256]; 
if (fgets(string, sizeof string, stdin) == NULL) { 
    /* handle failure */ 
} 
string[strcspn(string, "\n")] = 0; /* For removing the newline if present */ 

das ist less error prone und besser zu verstehen. Wenn Sie glibc verwenden, können Sie auch verwenden.

+0

Beachten Sie, dass das Format 'scanf()' keine leeren Zeilen lesen kann und einen Pufferüberlauf in Zeilen verursacht, die länger als das Zielarray sind. Der 'fgets()' Ansatz ist viel vorzuziehen, aber Sie sollten den Rückgabewert testen, bevor Sie versuchen, das '' \ n'' zu entfernen, da der Inhalt von 'string' unbestimmt ist, wenn 'fgets()' fehlschlägt und 'NULL' zurückgibt . – chqrlie

Verwandte Themen