Namespaces
Variants

std:: scanf, std:: fscanf, std:: sscanf

From de.cppreference.net
< cpp ‎ | io ‎ | c
Definiert in Header <cstdio>
int scanf ( const char * format, ... ) ;
(1)
int fscanf ( std:: FILE * stream, const char * format, ... ) ;
(2)
int sscanf ( const char * buffer, const char * format, ... ) ;
(3)

Liest Daten aus verschiedenen Quellen, interpretiert sie gemäß format und speichert die Ergebnisse an vorgegebenen Speicherorten.

1) Liest die Daten von stdin .
2) Liest die Daten aus dem Dateistrom stream .
3) Liest die Daten aus der nullterminierten Zeichenkette buffer .

Inhaltsverzeichnis

Parameter

stream - Eingabedateistrom, aus dem gelesen wird
buffer - Zeiger auf eine nullterminierte Zeichenkette, aus der gelesen wird
format - Zeiger auf eine nullterminierte Zeichenkette, die angibt, wie die Eingabe gelesen werden soll
... - empfangende Argumente

Die format-Zeichenkette besteht aus

  • Nicht-Leerzeichen-Multibyte-Zeichen außer %: Jedes solche Zeichen in der Formatzeichenkette konsumiert genau ein identisches Zeichen aus dem Eingabestrom oder führt dazu, dass die Funktion fehlschlägt, wenn das nächste Zeichen im Strom nicht gleich ist.
  • Leerzeichen: Jedes einzelne Leerzeichen in der Formatzeichenkette konsumiert alle verfügbaren aufeinanderfolgenden Leerzeichen aus der Eingabe (ermittelt, als ob std::isspace in einer Schleife aufgerufen würde). Beachten Sie, dass es keinen Unterschied zwischen "\n", " ", "\t\t" oder anderen Leerzeichen in der Formatzeichenkette gibt.
  • Konvertierungsspezifikationen. Jede Konvertierungsspezifikation hat das folgende Format:
  • Einleitendes %-Zeichen.
  • (optional) Unterdrückungszeichen für Zuweisung *. Wenn diese Option vorhanden ist, weist die Funktion das Ergebnis der Konvertierung keinem empfangenden Argument zu.
  • (optional) Ganze Zahl (größer als Null), die die maximale Feldbreite angibt, d.h. die maximale Anzahl von Zeichen, die die Funktion bei der durch die aktuelle Konvertierungsspezifikation angegebenen Konvertierung konsumieren darf. Beachten Sie, dass %s und %[ zu einem Pufferüberlauf führen können, wenn die Breite nicht angegeben ist.
  • (optional) Längenmodifikator, der die Größe des empfangenden Arguments angibt, d.h. den tatsächlichen Zieltyp. Dies beeinflusst die Konvertierungsgenauigkeit und Überlaufregeln. Der Standardzieltyp ist für jeden Konvertierungstyp unterschiedlich (siehe Tabelle unten).
  • Konvertierungsformatbezeichner.

Die folgenden Formatbezeichner sind verfügbar:

Konvertierung
Bezeichner
Erklärung Erwarteter
Argumenttyp
Längenmodifikator→ hh h keiner l ll j z t L
Nur verfügbar seit C++11→ Ja Ja Ja Ja Ja
%
Entspricht Literal %.
N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

Entspricht einem Zeichen oder einer Folge von Zeichen.

  • Wenn ein Breitenbezeichner verwendet wird, entspricht dies genau width Zeichen (das Argument muss ein Zeiger auf ein Array mit ausreichend Platz sein).
  • Im Gegensatz zu %s und %[, wird dem Array kein Nullzeichen angehängt.
N/A N/A
char*
wchar_t*
N/A N/A N/A N/A N/A
s

Entspricht einer Folge von Nicht-Leerzeichen (eine Zeichenkette).

  • Wenn ein Breitenbezeichner verwendet wird, werden bis zu width oder bis zum ersten Leerzeichen (je nachdem, was zuerst auftritt) erfasst.
  • Speichert immer zusätzlich zu den erfassten Zeichen ein Nullzeichen (daher muss das Argument-Array Platz für mindestens width+1 Zeichen haben).
[set ]

Entspricht einer nicht-leeren Folge von Zeichen aus set von Zeichen.

  • Wenn das erste Zeichen der Menge ^ ist, werden alle nicht in der Menge enthaltenen Zeichen erfasst.
  • Wenn die Menge mit ] oder ^] beginnt, dann wird das Zeichen ] ebenfalls in die Menge aufgenommen.
  • Es ist implementierungsdefiniert, ob das Zeichen - an einer nicht-initialen Position im Scanset einen Bereich angeben kann, wie in [0-9].
  • Wenn ein Breitenbezeichner verwendet wird, werden nur bis zu width erfasst.
  • Speichert immer zusätzlich zu den erfassten Zeichen ein Nullzeichen (daher muss das Argument-Array Platz für mindestens width+1 Zeichen haben).
d

Entspricht einer Dezimalzahl.

  • Das Zahlenformat ist dasselbe wie von std::strtol mit dem Wert 10 für das base-Argument erwartet.
signed char* oder unsigned char*
signed short* oder unsigned short*
signed int* oder unsigned int*
signed long* oder unsigned long*
signed long long* oder unsigned long long*
std::intmax_t* oder std::uintmax_t*
std::size_t*
std::ptrdiff_t*
N/A
b (C++26)

Entspricht einer vorzeichenlosen Binärzahl.

  • Das Zahlenformat ist dasselbe wie von std::strtoul mit dem Wert 2 für das base-Argument erwartet.
i

Entspricht einer ganzen Zahl.

  • Das Zahlenformat ist dasselbe wie von std::strtol mit dem Wert 0 für das base-Argument erwartet (die Basis wird durch die ersten geparsten Zeichen bestimmt).
u

Entspricht einer vorzeichenlosen Dezimalzahl.

  • Das Zahlenformat ist dasselbe wie von std::strtoul mit dem Wert 10 für das base-Argument erwartet.
o

Entspricht einer vorzeichenlosen Oktalzahl.

  • Das Zahlenformat ist dasselbe wie von std::strtoul mit dem Wert 8 für das base-Argument erwartet.
x
X

Entspricht einer vorzeichenlosen Hexadezimalzahl.

  • Das Zahlenformat ist dasselbe wie von std::strtoul mit dem Wert 16 für das base-Argument erwartet.
n

Gibt die Anzahl der bisher gelesenen Zeichen zurück.

  • Es wird keine Eingabe konsumiert. Erhöht nicht den Zuweisungszähler.
  • Wenn der Bezeichner einen Unterdrückungsoperator für Zuweisung definiert hat, ist das Verhalten undefiniert.
a (C++11)
A (C++11)
e
E
f
F (C++11)
g
G

Entspricht einer Gleitkommazahl.

  • Das Zahlenformat ist dasselbe wie von std::strtof erwartet.
N/A N/A
float*
double*
N/A N/A N/A N/A
long double*
p

Entspricht einer implementierungsdefinierten Zeichenfolge, die einen Zeiger definiert.

  • printfFamilie von Funktionen sollte die gleiche Sequenz unter Verwendung des %p-Formatbezeichners erzeugen.
N/A N/A
void**
N/A N/A N/A N/A N/A N/A
Anmerkungen

Für jeden Konvertierungsbezeichner außer n wird die längste Folge von Eingabezeichen, die keine angegebene Feldbreite überschreitet und die entweder genau das ist, was der Konvertierungsbezeichner erwartet, oder ein Präfix einer Sequenz, die er erwarten würde, aus dem Strom konsumiert. Das erste Zeichen, falls vorhanden, nach dieser konsumierten Sequenz bleibt ungelesen. Wenn die konsumierte Sequenz die Länge Null hat oder wenn die konsumierte Sequenz nicht wie oben angegeben konvertiert werden kann, tritt ein Übereinstimmungsfehler auf, es sei denn, Dateiende, ein Kodierungsfehler oder ein Lesefehler hat die Eingabe aus dem Strom verhindert, in welchem Fall es sich um einen Eingabefehler handelt.

Mit Ausnahme des %-Bezeichners wird das Eingabeelement (oder für %n die Anzahl der Eingabezeichen) zunächst in einen für den Konvertierungsbezeichner geeigneten Typ umgewandelt. Sofern die Zuweisung nicht mit * unterdrückt wurde, wird das Ergebnis der Konvertierung in das Objekt geschrieben, auf das das nächste noch nicht beschriebene Argument zeigt. Wenn dieses Objekt keinen geeigneten Typ hat oder wenn das Ergebnis der Konvertierung nicht im Objekt dargestellt werden kann, ist das Verhalten undefiniert.

Alle Konvertierungsbezeichner außer [, c und n konsumieren und verwerfen alle führenden Leerzeichen (ermittelt, als ob std::isspace aufgerufen würde), bevor sie versuchen, die Eingabe zu parsen. Diese konsumierten Zeichen zählen nicht zur angegebenen maximalen Feldbreite.

Die Konvertierungsbezeichner lc, ls und l[ führen eine Multibyte-zu-Breitzeichen-Konvertierung durch, als ob std::mbrtowc mit einem std::mbstate_t-Objekt aufgerufen würde, das vor der Konvertierung des ersten Zeichens auf Null initialisiert wurde.

Die Konvertierungsbezeichner s und [ speichern immer den Null-Terminator zusätzlich zu den übereinstimmenden Zeichen. Die Größe des Zielarrays muss mindestens um eins größer sein als die angegebene Feldbreite. Die Verwendung von %s oder %[ ohne Angabe der Zielarraygröße ist genauso unsicher wie std::gets.

Die korrekten Konvertierungsspezifikationen für die Ganzzahltypen mit fester Breite (std::int8_t, usw.) sind im Header <cinttypes> definiert (obwohl SCNdMAX, SCNuMAX, usw. gleichbedeutend mit %jd, %ju, usw. sind).

Es gibt einen Sequenzpunkt nach der Aktion jedes Konvertierungsbezeichners; dies ermöglicht das Speichern mehrerer Felder in derselben „Senken“-Variablen.

Beim Parsen eines unvollständigen Gleitkommawerts, der im Exponenten ohne Ziffern endet, wie z.B. das Parsen von "100er" mit dem Konvertierungsbezeichner %f, wird die Sequenz "100e" (das längste Präfix einer möglicherweise gültigen Gleitkommazahl) konsumiert, was zu einem Übereinstimmungsfehler führt (die konsumierte Sequenz kann nicht in eine Gleitkommazahl konvertiert werden), wobei "r" übrig bleibt. Einige vorhandene Implementierungen folgen dieser Regel nicht und setzen zurück, um nur "100" zu konsumieren, wobei "er" übrig bleibt, z.B. glibc Fehler 1765.

Wenn eine Konvertierungsspezifikation ungültig ist, ist das Verhalten undefiniert.

Rückgabewert

Anzahl der erfolgreich zugewiesenen empfangenen Argumente (die null sein kann, falls ein Übereinstimmungsfehler vor der Zuweisung des ersten empfangenen Arguments auftrat), oder EOF wenn ein Eingabefehler vor der Zuweisung des ersten empfangenen Arguments auftritt.

Komplexität

Nicht garantiert. Insbesondere sind einige Implementierungen von std::sscanf O(N) , wobei N = std:: strlen ( buffer ) [1] . Für performantes String-Parsing siehe std::from_chars .

Hinweise

Da die meisten Konvertierungsspezifizierer zunächst allen aufeinanderfolgenden Leerraum verarbeiten, Code wie

std::scanf("%d", &a);
std::scanf("%d", &b);

wird zwei Ganzzahlen lesen, die in verschiedenen Zeilen eingegeben werden (das zweite % d verarbeitet den von der ersten Eingabe übrig gebliebenen Zeilenumbruch) oder in derselben Zeile, getrennt durch Leerzeichen oder Tabs (das zweite % d verarbeitet die Leerzeichen oder Tabs).

The conversion specifiers that do not consume leading whitespace, such as % c , can be made to do so by using a whitespace character in the format string:
std::scanf("%d", &a);
std::scanf(" %c", &c); // Zeilenumbruch nach %d ignorieren, dann ein Zeichen einlesen

Beachten Sie, dass einige Implementierungen von std::sscanf einen Aufruf von std::strlen beinhalten, was ihre Laufzeit linear zur Länge der gesamten Zeichenkette macht. Das bedeutet, dass wenn std::sscanf in einer Schleife aufgerufen wird, um wiederholt Werte vom Anfang einer Zeichenkette zu parsen, Ihr Code in quadratischer Zeit laufen könnte ( Beispiel ).

Beispiel

#include <clocale>
#include <cstdio>
#include <iostream>
int main()
{
    int i, j;
    float x, y;
    char str1[10], str2[4];
    wchar_t warr[2];
    std::setlocale(LC_ALL, "en_US.utf8");
    char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";
    // parse as follows:
    // %d: an integer 
    // %f: a floating-point value
    // %9s: a string of at most 9 non-whitespace characters
    // %2d: two-digit integer (digits 5 and 6)
    // %f: a floating-point value (digits 7, 8, 9)
    // %*d an integer which isn't stored anywhere
    // ' ': all consecutive whitespace
    // %3[0-9]: a string of at most 3 digits (digits 5 and 6)
    // %2lc: two wide characters, using multibyte to wide conversion
    const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
                                &i, &x, str1, &j, &y, str2, warr);
    std::cout << "Converted " << ret << " fields:\n"
                 "i = " << i << "\n"
                 "x = " << x << "\n"
                 "str1 = " << str1 << "\n"
                 "j = " << j << "\n"
                 "y = " << y << "\n"
                 "str2 = " << str2 << std::hex << "\n"
                 "warr[0] = U+" << (int)warr[0] << "\n"
                 "warr[1] = U+" << (int)warr[1] << '\n';
}

Ausgabe:

Converted 7 fields:
i = 25
x = 5.432
str1 = Thompson
j = 56
y = 789
str2 = 56
warr[0] = U+df
warr[1] = U+6c34

Siehe auch

(C++11) (C++11) (C++11)
formatierten Eingang liest von stdin , einem Dateistrom oder einem Puffer
unter Verwendung einer variablen Argumentenliste
(Funktion)
liest eine Zeichenkette aus einem Dateistrom
(Funktion)
formatierten Ausgang schreibt auf stdout , einen Dateistrom oder einen Puffer
(Funktion)
(C++17)
konvertiert eine Zeichenfolge in einen Integer- oder Fließkommawert
(Funktion)
C-Dokumentation für scanf , fscanf , sscanf