Wie man sscanf richtig und sicher benutzt

8

Zunächst beantworten andere Fragen zur Verwendung von sscanf meine Frage nicht, da die allgemeine Antwort darin besteht, sscanf nicht zu verwenden und stattdessen fgets oder getch zu verwenden, was in meinem Fall nicht möglich ist .

Das Problem ist, mein C-Professor möchte, dass ich scanf in einem Programm verwende. Es ist eine Anforderung. Allerdings muss das Programm auch alle falschen Eingaben verarbeiten.

Das Programm muss ein Array von ganzen Zahlen lesen. Es ist egal in welchem ​​Format die ganzen Zahlen sind für das Array geliefert werden. Um die Aufgabe zu erleichtern, liest das Programm zuerst die Größe des Arrays und dann die Ganzzahlen jeweils in einer neuen Zeile.

Das Programm muss solche Eingaben verarbeiten (und Fehler entsprechend melden):

  1. 999999999999999 ... 9 (Zahlen größer als ganze Zahl)
  2. 12a3 (lies das nicht als Integer 12)
  3. a ... z (Zeichenfolgen)
  4. 11 aa 22 33 \ n alles in einer Zeile (dies könnte dadurch erledigt werden, dass alles nach 11 weggeworfen wird)
  5. Eingaben größer als das Eingabearray

Es könnte mehr falsche Fälle geben, das sind die einzigen, die mir einfallen.

Wenn die fehlerhafte Eingabe geliefert wird, muss das Programm den Benutzer bitten, erneut einzugeben, bis die korrekte Eingabe ist gegeben, aber die vorherige korrekte Eingabe muss beibehalten werden (nur inkorrekt) Eingang muss aus dem Eingangsstrom gelöscht werden).

Alles muss dem C99 Standard entsprechen.

    
evodevo 26.02.2012, 21:28
quelle

3 Antworten

10

Die Funktionsfamilie scanf kann nicht sicher verwendet werden, insbesondere im Umgang mit Ganzzahlen. Der erste von Ihnen erwähnte Fall ist besonders problematisch. Der Standard sagt das:

  

Wenn dieses Objekt keinen geeigneten Typ hat oder das Ergebnis von   Die Konvertierung kann nicht im Objekt dargestellt werden, das Verhalten ist   undefiniert.

Einfach und einfach. Sie könnten an %5d tricks und so weiter denken, aber Sie werden feststellen, dass sie nicht zuverlässig sind. Oder vielleicht wird jemand an Errno denken. Die Funktionen scanf müssen nicht errno festgelegt werden.

Folgen Sie diesem lustige kleine Seite verarbeiten können: sie enden damit, scanf zusammen zu löschen.

Gehen Sie also zu Ihrem C-Professor zurück und fragen Sie ihn: Wie genau schreibt C99 vor, dass sscanf Fehler melden wird?

?

    
cnicutar 26.02.2012, 21:35
quelle
1

Nun, lassen Sie sscanf alle Eingaben als% s (d. h. Zeichenfolgen) akzeptieren und programmieren Sie sie dann

    
mikithskegg 26.02.2012 21:31
quelle
1

Wenn Sie scanf verwenden müssen, um die Eingabe zu akzeptieren, denke ich, dass Sie mit etwas wie dem folgenden beginnen.

%Vor%

Damit wird (mehr oder weniger) das Problem der Eingabe im freien Format behandelt, da scanf automatisch führende Whitespaces überspringt, wenn ein %d -Format gefunden wird.

Die wichtigste Beobachtung für viele Ihrer Bedenken ist, dass scanf Ihnen sagt, wie viele Formatcodes erfolgreich analysiert wurden. Also,

%Vor%

Ich denke, dies behandelt direkt die Bedenken (3) und (4)

Für sich genommen ist dies nicht der Fall der Eingabe 12a3 . Beim ersten Durchlauf durch die Schleife würde scanf '12 as an integer 12, leaving the remaining a3 'für die nächste Schleife parsen. Sie würden jedoch beim nächsten Mal einen Fehler bekommen. Ist das gut genug für die Zwecke deines Professors?

Für Ganzzahlen größer als maxint , zB "999999 ....... 999", bin ich mir nicht sicher, was Sie mit geraden scanf tun können.

Für Eingaben, die größer als das Eingabearray sind, ist dies kein scanf Problem per se . Sie müssen nur zählen, wie viele Ganzzahlen Sie bisher analysiert haben.

Wenn Sie sscanf zum Dekodieren von Strings verwenden können, nachdem sie aus dem Eingabestream von etwas wie scanf("%s") extrahiert wurden, könnten Sie auch etwas ähnliches tun:

%Vor%

Dies funktioniert für jede Folge von Wörtern, die durch Leerzeichen getrennt sind, und Sie können die Eingabe für Wörter trennen und dann sehen, ob diese Wörter wie Zahlen aussehen oder nicht. Und wenn Sie müssen, können Sie scanf variants für jedes Teil verwenden.

    
Dale Hagglund 27.02.2012 00:52
quelle

Tags und Links