Frage

Ich habe eine Menge Probleme wurde mit versuchen, herauszufinden, wie scanf() zu verwenden. Es scheint, mit ganzen Zahlen zu funktionieren, recht geradlinig scanf("%d", &i) zu sein.

Wo ich in Probleme laufen lasse wird in Schleifen mit scanf() Eingabe zu lesen versuchen. Zum Beispiel:

do {
  printf("counter: %d: ", counter);
  scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
  1. Wenn ich in einer rechtsgültig strukturierten Eingabe wie c P101 eingeben, so scheint es Schleife wieder vor mir zu fragen. Dies scheint zu passieren, auch mit einem einzigen:

    scanf("%c", &c) 
    

    in einer while-Schleife. Es wird die Schleife tun zweimal vor mir wieder aufgefordert. Was ist es Schleife zweimal machen, und wie kann ich es stoppen?

  2. Wenn ich in weniger Menge an Eingang eingeben, die programmatisch nicht ein anderes Zeichen oder eine Zahl wie q haben würden, enter scheint mich aufzufordern, mehr zu betreten. Wie erhalte ich scanf() sowohl Einzel- als auch Doppelcharakter Einträge bearbeiten?

War es hilfreich?

Lösung

Wenn Sie „c P101“ das Programm eingeben tatsächlich erhält „c P101\n“. Die meisten der Konvertierungsspezifizierer überspringen Leerzeichen führende einschließlich Zeilenumbrüche aber %c nicht. Das erste Mal um alles bis bis der „\n“ gelesen wird, das zweite Mal, um den „\ n“ in command gelesen wird, „c“ in prefix gelesen, und „P“ gelassen wird, welche keine Zahl ist, so dass die Umwandlungs schlägt fehl, und „P101\n“ auf dem Strom links. Das nächste Mal „P“ in Befehl gespeichert ist, „1“ in Präfix gespeichert und 1 (aus dem verbleibenden „01“) wird in Eingang mit dem „\n“ noch auf dem Strom für die nächste Mal gespeichert. Sie können dieses Problem beheben, indem Sie ein Leerzeichen am Anfang des Formatstring setzen, das jede führende Leerzeichen inklusive Zeilenumbrüchen überspringen wird.

Eine ähnliche Sache ist für den zweiten Fall geschieht, wenn Sie „q“, „q\n“ eingeben, in den Strom eingegeben wird, wird das erste Mal, um die „q“ lesen, das zweite Mal der „\n“ gelesen wird, nur auf dem dritten Aufruf ist die zweite „q“ lesen, können Sie das Problem erneut vermeiden, indem Sie ein Leerzeichen am Anfang des Formatstrings hinzugefügt wird.

Eine bessere Möglichkeit, dies zu tun, wäre so etwas wie fgets () zu verwenden, eine Linie zu einem Zeitpunkt, zu verarbeiten und dann verwenden sscanf () die Analyse zu tun.

Andere Tipps

Es ist wirklich gebrochen! Ich wusste es nicht

#include <stdio.h>

int main(void)
{
    int counter = 1;
    char command, prefix;
    int input;

    do 
    {
        printf("counter: %d: ", counter);
        scanf("%c %c%d", &command, &prefix, &input);
        printf("---%c %c%d---\n", command, prefix, input);
        counter++;
    } while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
 c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
 g3---

Der Ausgang scheint mit Robert Antwort zu passen.

Wenn Sie die Zeichenfolge, die die Zeile enthält. das heißt "C P101", können Sie die Parsen Fähigkeiten von sscanf verwenden.

Siehe auch: http://www.cplusplus.com/reference/clibrary/cstdio/sscanf. html

Frage 1, vermute ich, dass Sie ein Problem mit Ihrem printf() haben, da es kein Abschluss ist „\ n“.

Das Standardverhalten von printf ausgegeben puffern, bis er eine komplette Linie hat. Das heißt, wenn Sie explizit die Pufferung auf stdout ändern.

Frage 2, haben Sie treffen nur eines der größten Probleme bei der scanf(). Es sei denn, Ihre Eingabe genau die Scan-Zeichenfolge übereinstimmt, dass Sie angegeben haben, Ihre Ergebnisse werden nichts sein wie das, was man erwartet.

Wenn Sie noch eine Option bekommen Sie bessere Ergebnisse haben werden (und weniger Sicherheitsprobleme) durch scanf() ignorieren und Ihre eigene Analyse zu tun. Verwenden Sie zum Beispiel fgets() eine ganze Zeile in einen String, lesen und dann die einzelnen Felder des Strings verarbeiten -. Vielleicht sogar mit sscanf()

Vielleicht eine while-Schleife verwenden, nicht eine do ... while-Schleife helfen. Auf diese Weise wird der Zustand vor der Ausführung des Codes getestet. Versuchen Sie, den folgenden Codeausschnitt:

 while(command != 'q')
    {
        //statements
    }

Auch wenn Sie die Stringlänge voraus zu wissen, ‚für‘ Schleifen können viel einfacher zu arbeiten als mit ‚while‘ Schleifen. Es gibt auch einige trickier Möglichkeiten, um dynamisch als auch die Länge zu bestimmen.

Als letzte Tirade: „saugen“ scanf() nicht Es tut, was es tut und das ist alles. fgets() ist sehr gefährlich (wenn auch bequem für No-Risk-Anwendungen), da es nicht nativ jede Überprüfung der Eingabe macht. Es ist sehr häufig als Punkt bekannt ausnutzen, insbesondere Überlaufangriffe Puffer, Überschreiben Raum in den Registern nicht für diese Variable zugeordnet. Deshalb, wenn Sie es verwenden möchten, verbringen Sie einige Zeit in eine feste Fehlerprüfung / Korrektur setzen.

Hope dies hilft jemand in der Zukunft, da ich Sie davon ausgehen, habe es jetzt behandelt habe! ;)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top