std:: scanf, std:: fscanf, std:: sscanf
|
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.
Inhaltsverzeichnis |
Parameter
| stream | - | Eingabedateistream zum Lesen |
| buffer | - | Zeiger auf einen nullterminierten Zeichenstring zum Lesen |
| format | - | Zeiger auf einen nullterminierten Zeichenstring, der die Eingabeart spezifiziert |
| ... | - | empfangende Argumente |
Die Format -Zeichenkette besteht aus
- Nicht-Leerzeichen-Multibyte-Zeichen außer % : Jedes solche Zeichen in der Formatzeichenfolge 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.
- Leerzeichenzeichen: Jedes einzelne Leerzeichenzeichen in der Formatzeichenfolge konsumiert alle verfügbaren aufeinanderfolgenden Leerzeichenzeichen aus der Eingabe (bestimmt wie durch wiederholtes Aufrufen von std::isspace ). Beachten Sie, dass es keinen Unterschied zwischen " \n " , " " , " \t \t " oder anderen Leerzeichen in der Formatzeichenfolge gibt.
- Konvertierungsspezifikationen. Jede Konvertierungsspezifikation hat folgendes Format:
-
- Einleitendes % Zeichen.
-
- (optional) unterdrückendes Zuweisungszeichen * . Wenn diese Option vorhanden ist, weist die Funktion das Ergebnis der Konvertierung keinem empfangenden Argument zu.
-
- (optional) Ganzzahl (größer als Null), die die maximale Feldbreite angibt, also die maximale Anzahl an Zeichen, die die Funktion bei der Durchführung der durch die aktuelle Konvertierungsangabe spezifizierten Konvertierung verarbeiten darf. Beachten Sie, dass % s und % [ zu Pufferüberlauf führen können, wenn die Breite nicht angegeben wird.
-
- (optional) Längenmodifikator , der die Größe des empfangenden Arguments angibt, also den tatsächlichen Zieltyp. Dies beeinflusst die Konvertierungsgenauigkeit und Überlaufregeln. Der Standardzieltyp ist für jeden Konvertierungstyp unterschiedlich (siehe Tabelle unten).
-
- Konvertierungsformat-Spezifizierer.
Die folgenden Formatbezeichner sind verfügbar:
|
Konvertierungsspezifizierer
|
Erklärung |
Erwarteter
Argumenttyp |
||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Längenmodifikator→ |
hh
|
h
|
keine |
l
|
ll
|
j
|
z
|
t
|
L
|
|
| Nur verfügbar seit C++11→ | Ja | Ja | Ja | Ja | Ja | |||||
%
|
Entspricht dem 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 .
|
N/A | N/A |
char
*
|
wchar_t
*
|
N/A | N/A | N/A | N/A | N/A |
s
|
Entspricht einer Folge von Nicht-Leerzeichen (einem string ).
|
|||||||||
[
set
]
|
Entspricht einer nicht-leeren Zeichenfolge aus der set von Zeichen.
|
|||||||||
d
|
Passt auf eine dezimale Ganzzahl .
|
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
*
|
N/A | ||
i
|
Erkennt eine Ganzzahl .
|
|||||||||
u
|
Entspricht einem vorzeichenlosen Dezimalzahl .
|
|||||||||
o
|
Entspricht einer vorzeichenlosen Oktalzahl .
|
|||||||||
x
X
|
Erkennt einen vorzeichenlosen hexadezimalen Integer .
|
|||||||||
n
|
Gibt die Anzahl der bisher gelesenen Zeichen zurück.
|
|||||||||
a
(C++11)
A
(C++11)
e
E
f
F
(C++11)
g
G
|
Passt auf eine Gleitkommazahl .
|
N/A | N/A |
float
*
|
double
*
|
N/A | N/A | N/A | N/A |
long
double
*
|
p
|
Entspricht einer implementierungsdefinierten Zeichensequenz, die einen Zeiger definiert.
|
N/A | N/A |
void
**
|
N/A | N/A | N/A | N/A | N/A | N/A |
| Hinweise | ||||||||||
|
Für jeden Konvertierungsspezifizierer außer n wird die längste Folge von Eingabezeichen, die keine spezifizierte Feldbreite überschreitet und die entweder genau dem entspricht, was der Konvertierungsspezifizierer erwartet, oder ein Präfix einer solchen Folge ist, aus dem Stream gelesen. Das erste Zeichen nach dieser gelesenen Folge bleibt ungelesen. Wenn die gelesene Folge die Länge null hat oder wenn die gelesene Folge nicht wie oben spezifiziert konvertiert werden kann, tritt ein Übereinstimmungsfehler auf, es sei denn, das Dateiende, ein Kodierungsfehler oder ein Lesefehler verhinderten die Eingabe aus dem Stream, in welchem Fall es sich um einen Eingabefehler handelt. Alle Konvertierungsspezifizierer außer [ , c und n lesen und verwerfen alle führenden Leerzeichen (bestimmt wie durch Aufruf von std::isspace ), bevor sie versuchen, die Eingabe zu parsen. Diese gelesenen Zeichen zählen nicht zur spezifizierten maximalen Feldbreite. Die Konvertierungsspezifizierer lc , ls und l [ führen eine Multibyte-zu-Breitzeichen-Konvertierung durch, wie durch Aufruf von std::mbrtowc mit einem std::mbstate_t -Objekt, das vor der Konvertierung des ersten Zeichens auf null initialisiert wurde. Die Konvertierungsspezifizierer s und [ speichern immer den Nullterminator zusätzlich zu den übereinstimmenden Zeichen. Die Größe des Zielarrays muss mindestens um eins größer sein als die spezifizierte Feldbreite. Die Verwendung von % s oder % [ ohne Angabe der Zielarraygröße ist genauso unsicher wie std::gets . Die korrekten Konvertierungsspezifikationen für die Festbreiten-Ganzzahltypen ( std::int8_t usw.) sind im Header <cinttypes> definiert (obwohl SCNdMAX , SCNuMAX usw. synonym mit % jd , % ju usw. ist). Es gibt einen Sequenzpunkt nach der Aktion jedes Konvertierungsspezifizierers; dies ermöglicht das Speichern mehrerer Felder in derselben "Senken"-Variable. Beim Parsen eines unvollständigen Gleitkommawerts, der im Exponenten ohne Ziffern endet, wie z.B. das Parsen von "100er" mit dem Konvertierungsspezifizierer % f , wird die Sequenz "100e" (das längste Präfix einer möglicherweise gültigen Gleitkommazahl) gelesen, was zu einem Übereinstimmungsfehler führt (die gelesene Sequenz kann nicht in eine Gleitkommazahl konvertiert werden), wobei "r" übrig bleibt. Einige bestehende Implementierungen befolgen diese Regel nicht und rollen zurück, um nur "100" zu lesen, und lassen "er" übrig, z.B. glibc bug 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) |
|
|
(C++11)
|
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
|
|