Namespaces
Variants

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

From fr.cppreference.net
< cpp ‎ | io ‎ | c
Défini dans l'en-tête <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)

Lit les données depuis diverses sources, les interprète selon le format et stocke les résultats dans les emplacements spécifiés.

1) Lit les données depuis stdin .
2) Lit les données du flux de fichier stream .
3) Lit les données de la chaîne de caractères terminée par un caractère nul buffer .

Contenu

Paramètres

flux - flux de fichier d'entrée à lire
tampon - pointeur vers une chaîne de caractères terminée par un caractère nul à lire
format - pointeur vers une chaîne de caractères terminée par un caractère nul spécifiant comment lire l'entrée
... - arguments de réception

La format chaîne de format se compose de

  • caractères multi-octets non blancs sauf % : chaque caractère de ce type dans la chaîne de format consomme exactement un caractère identique depuis le flux d'entrée, ou fait échouer la fonction si le caractère suivant du flux n'est pas égal.
  • caractères blancs : tout caractère blanc dans la chaîne de format consomme tous les caractères blancs consécutifs disponibles depuis l'entrée (déterminé comme si en appelant std::isspace en boucle). Notez qu'il n'y a pas de différence entre "\n", " ", "\t\t", ou d'autres blancs dans la chaîne de format.
  • spécifications de conversion. Chaque spécification de conversion a le format suivant :
  • caractère d'introduction %.
  • (optionnel) caractère de suppression d'affectation *. Si cette option est présente, la fonction n'affecte le résultat de la conversion à aucun argument de réception.
  • (optionnel) nombre entier (supérieur à zéro) qui spécifie largeur de champ maximale, c'est-à-dire le nombre maximal de caractères que la fonction est autorisée à consommer lors de la conversion spécifiée par la spécification de conversion courante. Notez que %s et %[ peuvent conduire à un débordement de tampon si la largeur n'est pas fournie.
  • (optionnel) modificateur de longueur qui spécifie la taille de l'argument de réception, c'est-à-dire le type de destination réel. Cela affecte la précision de la conversion et les règles de débordement. Le type de destination par défaut est différent pour chaque type de conversion (voir tableau ci-dessous).
  • spécificateur de format de conversion.

Les spécificateurs de format suivants sont disponibles :

Conversion
spécificateur
Explication Type
d'argument attendu
Modificateur de longueur → hh h aucun l ll j z t L
Uniquement disponible depuis C++11 → Oui Oui Oui Oui Oui
%
Correspond au littéral %.
N/D N/D N/D N/D N/D N/D N/D N/D N/D
c

Correspond à un caractère ou à une séquence de caractères.

  • Si un spécificateur de largeur est utilisé, correspond exactement à largeur caractères (l'argument doit être un pointeur vers un tableau avec suffisamment d'espace).
  • Contrairement à %s et %[, n'ajoute pas le caractère nul au tableau.
N/D N/D
char*
wchar_t*
N/D N/D N/D N/D N/D
s

Correspond à une séquence de caractères non blancs (une chaîne).

  • Si un spécificateur de largeur est utilisé, correspond jusqu'à largeur ou jusqu'au premier caractère blanc, selon celui qui apparaît en premier.
  • Stocke toujours un caractère nul en plus des caractères correspondants (donc le tableau d'arguments doit avoir de la place pour au moins largeur+1 caractères).
[ensemble ]

Correspond à une séquence non vide de caractères provenant de l'ensemble de caractères.

  • Si le premier caractère de l'ensemble est ^, alors tous les caractères qui ne sont pas dans l'ensemble sont mis en correspondance.
  • Si l'ensemble commence par ] ou ^], alors le caractère ] est également inclus dans l'ensemble.
  • Défini par l'implémentation si le caractère - en position non initiale dans l'ensemble de balayage peut indiquer une plage, comme dans [0-9].
  • Si un spécificateur de largeur est utilisé, correspond seulement jusqu'à largeur.
  • Stocke toujours un caractère nul en plus des caractères correspondants (donc le tableau d'arguments doit avoir de la place pour au moins largeur+1 caractères).
d

Correspond à un entier décimal.

  • Le format du nombre est le même que celui attendu par std::strtol avec la valeur 10 pour l'argument base.
signed char* ou unsigned char*
signed short* ou unsigned short*
signed int* ou unsigned int*
signed long* ou unsigned long*
signed long long* ou unsigned long long*
std::intmax_t* ou std::uintmax_t*
std::size_t*
std::ptrdiff_t*
N/D
b (C++26)

Correspond à un entier binaire non signé.

  • Le format du nombre est le même que celui attendu par std::strtoul avec la valeur 2 pour l'argument base.
i

Correspond à un entier.

  • Le format du nombre est le même que celui attendu par std::strtol avec la valeur 0 pour l'argument base (la base est déterminée par les premiers caractères analysés).
u

Correspond à un entier décimal non signé.

  • Le format du nombre est le même que celui attendu par std::strtoul avec la valeur 10 pour l'argument base.
o

Correspond à un entier octal non signé.

  • Le format du nombre est le même que celui attendu par std::strtoul avec la valeur 8 pour l'argument base.
x
X

Correspond à un entier hexadécimal non signé.

  • Le format du nombre est le même que celui attendu par std::strtoul avec la valeur 16 pour l'argument base.
n

Retourne le nombre de caractères lus jusqu'à présent.

  • Aucune entrée n'est consommée. N'incrémente pas le compteur d'affectations.
  • Si le spécificateur a un opérateur de suppression d'affectation défini, le comportement est indéfini.
a (C++11)
A (C++11)
e
E
f
F (C++11)
g
G

Correspond à un nombre à virgule flottante.

  • Le format du nombre est le même que celui attendu par std::strtof.
N/D N/D
float*
double*
N/D N/D N/D N/D
long double*
p

Correspond à une séquence de caractères définie par l'implémentation définissant un pointeur.

  • printf Les fonctions de la famille %p doivent produire la même séquence en utilisant le spécificateur de format
N/D N/D
void**
N/D N/D N/D N/D N/D N/D
Notes

Pour chaque spécificateur de conversion autre que n, la séquence la plus longue de caractères d'entrée qui ne dépasse aucune largeur de champ spécifiée et qui est exactement ce que le spécificateur de conversion attend ou est un préfixe d'une séquence qu'il attendrait, est ce qui est consommé depuis le flux. Le premier caractère, s'il y en a un, après cette séquence consommée reste non lu. Si la séquence consommée a une longueur nulle ou si la séquence consommée ne peut pas être convertie comme spécifié ci-dessus, l'échec de correspondance se produit sauf si la fin de fichier, une erreur de codage ou une erreur de lecture a empêché l'entrée depuis le flux, auquel cas il s'agit d'un échec d'entrée.

À l'exception du spécificateur %, l'élément d'entrée (ou, pour %n, le nombre de caractères d'entrée) est d'abord converti en un type approprié au spécificateur de conversion. Sauf si l'affectation a été supprimée avec *, le résultat de la conversion est écrit dans l'objet pointé par l'argument suivant qui n'a pas encore été écrit. Si cet objet n'a pas un type approprié, ou si le résultat de la conversion ne peut pas être représenté dans l'objet, le comportement est indéfini.

Tous les spécificateurs de conversion autres que [, c et n consomment et jettent tous les caractères blancs de tête (déterminé comme si en appelant std::isspace) avant de tenter d'analyser l'entrée. Ces caractères consommés ne comptent pas dans la largeur de champ maximale spécifiée.

Les spécificateurs de conversion lc, ls et l[ effectuent une conversion multi-octets vers caractères larges comme si en appelant std::mbrtowc avec un objet std::mbstate_t initialisé à zéro avant que le premier caractère soit converti.

Les spécificateurs de conversion s et [ stockent toujours le terminateur nul en plus des caractères correspondants. La taille du tableau de destination doit être au moins supérieure d'un à la largeur de champ spécifiée. L'utilisation de %s ou %[, sans spécifier la taille du tableau de destination, est aussi dangereuse que std::gets.

Les spécifications de conversion correctes pour les types entiers à largeur fixe (std::int8_t, etc.) sont définies dans l'en-tête <cinttypes> (bien que SCNdMAX, SCNuMAX, etc. soient synonymes de %jd, %ju, etc.).

Il y a un point de séquence après l'action de chaque spécificateur de conversion ; cela permet de stocker plusieurs champs dans la même variable « de réception ».

Lors de l'analyse d'une valeur à virgule flottante incomplète qui se termine par l'exposant sans chiffres, comme l'analyse de "100er" avec le spécificateur de conversion %f, la séquence "100e" (le plus long préfixe d'un nombre à virgule flottante potentiellement valide) est consommée, résultant en une erreur de correspondance (la séquence consommée ne peut pas être convertie en un nombre à virgule flottante), avec "r" restant. Certaines implémentations existantes ne suivent pas cette règle et reviennent en arrière pour ne consommer que "100", laissant "er", par exemple, glibc bug 1765.

Si une spécification de conversion est invalide, le comportement est indéfini.

Valeur de retour

Nombre d'arguments de réception assignés avec succès (qui peut être zéro dans le cas où un échec de correspondance est survenu avant l'assignation du premier argument de réception), ou EOF si une erreur d'entrée survient avant l'assignation du premier argument de réception.

Complexité

Non garanti. Notamment, certaines implémentations de std::sscanf sont O(N) , où N = std:: strlen ( buffer ) [1] . Pour l'analyse performante de chaînes, voir std::from_chars .

Notes

Étant donné que la plupart des spécificateurs de conversion consomment d'abord tous les espaces blancs consécutifs, un code tel que

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

lira deux entiers qui sont saisis sur des lignes différentes (le second % d consommera le saut de ligne laissé par le premier) ou sur la même ligne, séparés par des espaces ou des tabulations (le second % d consommera les espaces ou les tabulations).

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); // ignorer le saut de ligne après %d, puis lire un caractère

Notez que certaines implémentations de std::sscanf impliquent un appel à std::strlen , ce qui rend leur temps d'exécution linéaire par rapport à la longueur de la chaîne entière. Cela signifie que si std::sscanf est appelé dans une boucle pour analyser répétitivement des valeurs au début d'une chaîne, votre code pourrait s'exécuter en temps quadratique ( exemple ).

Exemple

#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ß水";
    // analyse comme suit :
    // %d : un entier
    // %f : une valeur en virgule flottante
    // %9s : une chaîne d'au plus 9 caractères non-blancs
    // %2d : un entier à deux chiffres (chiffres 5 et 6)
    // %f : une valeur en virgule flottante (chiffres 7, 8, 9)
    // %*d : un entier qui n'est stocké nulle part
    // ' ' : tous les espaces blancs consécutifs
    // %3[0-9] : une chaîne d'au plus 3 chiffres (chiffres 5 et 6)
    // %2lc : deux caractères larges, utilisant la conversion multioctet vers large
    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';
}

Sortie :

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

Voir aussi

(C++11) (C++11) (C++11)
lit une entrée formatée depuis stdin , un flux de fichier ou un tampon
en utilisant une liste d'arguments variables
(fonction)
obtient une chaîne de caractères depuis un flux de fichier
(fonction)
imprime une sortie formatée vers stdout , un flux de fichier ou un tampon
(fonction)
(C++17)
convertit une séquence de caractères en une valeur entière ou à virgule flottante
(fonction)
Documentation C pour scanf , fscanf , sscanf