Fonctions fscanf, scanf et sscanf

Entête à inclure

#include <stdio.h>  // <cstdio> en C++

Fonctions fscanf, scanf et sscanf

int fscanf( FILE * stream, const char *format, ... );
int scanf( const char *format, ... );
int sscanf( const char * buffer, const char *format, ... );

Ces trois fonctions sont à la fois proches et différentes. Le point commun, c'est qu'elles permettent toutes d'extraire des données à partir d'une chaîne d'un flux (ou d'une chaîne de caractères pour la fonction sscanf) en utilisant un langage de formatage simple et efficace. En fait, le langage de formatage utilisé est le même que celui utilisé par les fonctions fprintf et assimilées.

Comment fonctionne le langage de formatage ? En fait c'est relativement simple : une chaîne de caractères définie des points d'extractions pour les paramètres qui sont passés à la suite du paramètres de format. Ces points d'extractions sont typés. Par exemple, le format "%d %d" spécifie qu'on cherche à extraire deux valeurs entières. Ainsi, l'appel scanf("%d %d", &a, &b) cherchera à extraire deux valeurs entières à partir de stdin : les valeurs extraites seront placées dans les deux variable a et b (comme en sortie de l'appel à scanf les paramètres devront être modifiés, c'est bien l'adresse de chacunes de des deux variables que l'on passe en paramètre).

Le tableau suivant vous propose les principaux formats utilisable avec les fonctions précisées dans cette page.

%d
Une donnée entière de type int
%ld
Une donnée entière de type long.
%f
Une donnée décimale de type float.
%lf
Une donnée décimale de type double.
%c
Une donnée de type caractère.
%p
Une donnée de type adresse en mémoire. Cette adresse sera présentée sous forme hexadécimale.
%s
Une donnée de type chaîne de caractères. Attention, tout séparateur (blanc, tabulation, retour à la ligne) interrompra la lecture.
%[characters]
Un donnée de type chaîne de caractères, constituée que de caractères parmis ceux spécifiés.
%[^characters]
Un donnée de type chaîne de caractères, constituée de tous caractères sauf les caractères spécifiés.

Astuce : imaginons que vous cherchiez à lire le contenu d'une ligne de texte (jusqu'au prochain caractère '\n') à partir du flux stdout. Dans ce cas, un scanf( "%s", buffer ) ne fonctionnera pas dans tous les cas. Effectivement, par défaut, la fonction scanf lira les caractères jusqu'au prochain séparateur (blanc, tabulation ou retour à la ligne). Ainsi, si vous saisissez comme ligne "Hello World", seul le mot Hello sera stocké dans buffer. Pour régler ce problème, utilisez plutôt scanf( "%[^\n]", buffer ). Cela signifie de lire tout sauf les retours à la ligne (ce qui stoppera la lecture).

Paramètres

Valeur de retour

Si aucune donnée ne peut être extraite, alors la valeur EOF vous sera retournée. Sinon, le nombre de paramètres correctement extraits vous sera renvoyé. Il est possible que seule une sous-partie des paramètres est pu être extraits (forcément les n premiers).

Exemple de code

#include <stdio.h>

int main( int argc, char * argv[] ) {
    
    int num;
    int den;
    double result;
    char buffer[80];
    
    printf( "Veuillez saisir votre nom : " );
    fflush( stdout );
    scanf( "%[^\n]", buffer );
    fgetc( stdin );   /* to delete '\n' character */        

    printf( "Veuillez saisir une fraction (sous la forme [num/den]) : " );
    fflush( stdout );
    scanf( "[%d/%d]", &num, &den );
    result = num / (double) den;
    
    printf( "%s a saisi %lf\n", buffer, result );
        
    return 0;
}

Voici le résultat de l'exécution de cet exemple.

$> gcc -o Sample -Wall Sample.c
$> ./Sample
Veuillez saisir votre nom : De La Vega
Veuillez saisir une fraction (sous la forme [num/den]) : [1/3]
De La Vega a saisi 0.333333
$>

Sujets connexes

fprintf
printf
sprintf