14 Stimmen

Die Verwendung von scanf zum Lesen eines Strings und einer Ganzzahl, die durch / getrennt sind

Die Eingabe besteht aus einem String und einer Ganzzahl, die durch ein '/' getrennt sind, wie zum Beispiel:

hallo/17

Und ich möchte die Eingabe in einen String und eine int einlesen, wie zum Beispiel:

char str[20];
int num;
scanf("%s/%d", str, &num);  // So habe ich es versucht.

Ich scheine es nicht hinbekommen, hast du einen Rat?

0 Stimmen

Interessante Frage. scanf könnte etwas haben, um mehr als nur mit %s übereinzustimmen.

0 Stimmen

Vergessen Sie nicht, beim Verwenden von %s oder %[ Konvertierungen eine Feldbreite anzugeben! Wir mögen keine Pufferüberläufe...

17voto

scanf wartet beim Versuch, %s zu lesen, auf einen durch Leerzeichen beendeten String.

Versuchen Sie, das verbotene Zeichenset direkt anzugeben:

  scanf("%19[^/]/%d", str, &num);

Sie können hier mehr über die Formatierungscodes lesen .

9voto

paxdiablo Punkte 809679

Sie müssen nur das folgende Programm ausführen:

#include 

int main (void) {
    char str[20] = {'\0'};
    int count, num = 42;

    count = sscanf ("hello/17", "%s/%d", str, &num);

    printf ("String war '%s'\n", str);
    printf ("Nummer war %d\n", num);
    printf ("Anzahl  war %d\n", count);

    return 0;
}

um zu sehen, warum das passiert. Die Ausgabe ist:

String war 'hello/17'
Nummer war 42
Anzahl  war 1

Der Grund hat mit dem %s Formatbezeichner zu tun. Aus C99 7.19.6.2 Die Funktion fscanf (weitgehend unverändert in C11, und die Kursivschrift ist von mir):

s: entspricht einer Sequenz von Nicht-Weißraum Zeichen.

Weil / kein Leerzeichen ist, wird es im Stringteil enthalten, genauso wie die 17 aus dem gleichen Grund. Das wird auch durch die Tatsache angezeigt, dass sscanf 1 zurückgibt, was bedeutet, dass nur ein Element gescannt wurde.

Was Sie also suchen werden, ist etwas, das Zeichen außer / in den String scannt (einschließlich Leerzeichen). Derselbe Abschnitt des Standards hilft auch dabei:

[: entspricht einer nichtleeren Sequenz von Zeichen aus einer Reihe erwarteter Zeichen (dem Scanset). Der Umwandlungsspezifikator enthält alle nachfolgenden Zeichen in der Formatzeichenkette, bis einschließlich der zugehörigen rechten Klammer (]). Die Zeichen zwischen den Klammern (der Scanliste) bilden das Scanset, es sei denn, das Zeichen nach der linken Klammer ist ein Zirkumflex (^), in diesem Fall enthält das Scanset alle Zeichen, die nicht in der Scanliste zwischen dem Zirkumflex und der rechten Klammer erscheinen.

Mit anderen Worten, etwas wie:

#include 
int main (void) {
    char str[20] = {'\0'};
    int count, num = 42;

    count = sscanf ("hello/17", "%[^/]/%d", str, &num);

    printf ("String war '%s'\n", str);
    printf ("Nummer war %d\n", num);
    printf ("Anzahl  war %d\n", count);

    return 0;
}

was Ihnen gibt:

String war 'hello'
Nummer war 17
Anzahl  war 2

Noch ein weiterer Ratschlag: verwenden Sie niemals scanf mit einem ungebundenen %s oder %[; Sie sind damit anfällig für Pufferüberlaufangriffe. Wenn Sie eine robuste Benutzereingabefunktion möchten, sehen Sie sich diese Antwort an.

Sobald Sie es als String haben, können Sie es ohne Sorgen vor Pufferüberlauf mit sscanf verwenden (da Sie die Größe bei der Eingabe begrenzt haben).

0voto

Könnte so aussehen:

char str[20];
int num;

scanf("%19[^/]%*c%d", str, &num);

%*c liest ein Zeichen ein und verwirft es

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X