IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Notes sur le langage C

Notes sur le langage C


prcdentsommairesuivant

XXXII. Saisie de donnes par un oprateur (stdin)

XXXII-A. Introduction

Il est courant en C standard d'utiliser le flux stdin pour acqurir des donnes en provenance d'un oprateur. (Mode conversationnel). On admettra pour la suite que stdin est connect la partie 'clavier' d'un priphrique console.

Le langage C offre plusieurs fonctions permettant de lire des donnes sur un flux en gnral et sur stdin en particulier.

  • fgetc()
  • getc()
  • getchar()
  • gets()
  • scanf()
  • fgets()

XXXII-B. fgetc(), getc(), getchar()

Ces trois fonctions extraient un caractre du flux entrant (pour getchar(), ce flux est stdin). C'est insuffisant pour saisir autre chose qu'un simple <ENTER>. Ces fonctions ne sont absolument pas adaptes la saisie d'un caractre comme un choix de menu par exemple.

Par contre, ces fonctions peuvent tre utilises pour construire des fonctions d'entres de plus haut niveau plus ou moins spcialises.

Dtails de fonctionnement de fgetc()

XXXII-C. gets()

Pour des raisons videntes de scurit (pas de limitation du nombre de caractres saisis), la fonction gets() ne devrait pas tre utilise. Bien que, ma connaissance, cette fonction ne soit pas officiellement dprcie pour des raisons de compatibilit avec le code existant, il est fortement conseill de ne pas l'utiliser pour de nouveaux dveloppements.

XXXII-D. scanf()

Malgr ce que l'on constate dans l'abondante littrature consacre l'initiation au langage C, l'utilisation de scanf() n'est pas adapte.

En effet, le 'f' de scanf() est l pour nous rappeler que l'entre doit tre formate (formated), ce qui n'est videmment pas le cas avec un oprateur humain qui peut entrer n'importe quoi. D'autre part, scanf() gre difficilement le '\n', ce qui entraine des comportements aberrants dans les saisies si on ne prend pas certaines prcautions d'usage.

L'utilisation correcte et sre de scanf() est complexe, et n'est pas la port d'un dbutant (ni mme celle de la plupart des programmeurs expriments). Nanmoins, il est possible d'utiliser correctement scanf() si on se forme correctement. En lisant par exemple l'article Scanf dmythifie.

XXXII-E. fgets()

Cette fonction est parfaitement adapte la saisie d'une ligne, (mme de 1 caractre). Son usage est recommand.

S'il faut saisir une valeur numrique, celle-ci sera d'abord saisie sous forme de ligne, puis traduite par la fonction approprie (strtol(), strtoul(), strtod()) ou sscanf()) avec le filtre appropri :

 
Sélectionnez
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
   int ret;
   char temp[20];
 
   do
   {
      char saisie[20];
 
      printf("Entrez un nombre : ");
      fflush (stdout);
 
      fgets (saisie, sizeof saisie, stdin);
 
      /* Filtrage des caracteres (entier decimal)
       * Nota : la saisie s'arrete a la premiere erreur.
       * Ce qui est saisi avant est considere comme valide.
       *
       * "123a" -> "123" : ret = 1
       *
       * "a123" -> ""    : ret = 0
       */
      ret = sscanf (saisie, "%[0-9-]s", temp);
   }
   while (ret != 1);
 
   {
      long n = strtol (temp, NULL, 10);
 
      printf ("La chaine est '%s', soit %ld\n", temp, n);
   }
   return 0;
}

D'autres exemples dans le chapitre sur les fichiers

XXXII-F. Ressources

XXXII-G. Comment fonctionne fgetc(stdin) alias getchar()

Cette fonction d'apparence simple a en fait un comportement plus complexe qu'il n'y parait. En effet, elle regroupe un certain nombre de comportements non triviaux qui sont rarement expliqus dans la littrature C.

XXXII-G-1. Comportement visible.

L'appel de cette fonction provoque une suspension de l'excution du programme. Durant cette suspension, il est possible de rentrer des caractres (par exemple l'aide du clavier) et mme ventuellement de supprimer le ou les derniers caractres saisis l'aide de la touche 'BackSpace'. La fin de saisie (et la reprise de l'excution du programme) est marque par la frappe de la touche <enter>.

XXXII-G-2. Comportement interne.

Les caractres saisis sont stocks dans le flux stdin. Lorsque l'on frappe la touche <enter>, le caractre '\n' est aussi plac dans stdin, et l'excution reprend. Le caractre le plus ancien est alors extrait du flux et il est retourn. En cas d'erreur de lecture ou d'entre d'un caractre spcial dit 'de fin de fichier' (Ctrl-D, Ctrl-Z etc. selon le systme), la valeur EOF (int < 0) est retourne.

Ensuite, si on rappelle fgetc(), deux cas sont possibles. Soit le flux est vide, soit il ne l'est pas. Si le flux est vide, la fonction fgetc() suspend l'excution, et on retrouve le comportement prcdent. S'il n'est pas vide, l'excution n'est pas suspendue, et le caractre le plus ancien est extrait et retourn.

Dans la grande majorit des cas la lecture du '\n' signifie que la ligne saisie a t compltement lue.

XXXII-G-3. Quelques exprimentations.

A l'aide de simples programmes, il est possible de vrifier un certain nombre de comportements dcrits prcdemment :

 
Sélectionnez
#include <stdio.h>
 
int main (void)
{
 
   int x = fgetc(stdin);
 
   printf ("x = %d ('%c')\n", x, x);
 
   return 0;
}

Quelques essais de saisie :

 
Sélectionnez
<enter>
x = 10 ('
')

On voit que le caractre extrait est '\n' (ici, LF, soit le code ASCII 10)

 
Sélectionnez
a<enter>
x = 97 ('a')

On voit que le caractre extrait est 'a' (ici, le code ASCII 97). Le <enter> ('\n') n'a pas t extrait. Si on appelait fgetc() une nouvelle fois, il n'y aurait pas de suspension.

 
Sélectionnez
a<backspace>b<enter>
x = 98 ('b')

On constate que, bien que le premier caractre saisi fut 'a', le caractre extrait est 'b' (ici, le code ASCII 98). En effet, la touche <backspace> a permis de corriger la dernire saisie.

 
Sélectionnez
abcd<enter>
x = 97 ('a')

On voit que le caractre extrait est 'a', bien que d'autres caractres aient t saisis aprs. C'est donc bien le plus ancien caractre qui est extrait. Les autres caractres sont en attente de lecture. Une boucle de fgetc() permettrait de les extraire.

 
Sélectionnez
#include <stdio.h>
 
int main (void)
{
   int x;
 
   do
   {
      x = fgetc(stdin);
      printf ("x = %d ('%c')\n", x, x);
   }
   while (1);
 
   return 0;
}

Je laisse au lecteur le soin de refaire les expriences prcdentes et d'en tirer les conclusions qui s'imposent.

XXXIII. Les fichiers

XXXIII-A. Introduction

Le langage C n'offre pas, proprement parler, de gestion de fichiers. Il dfinit plutt des flux d'entres / sorties (I/O streams) sur lesquels il peut agir (ouverture/fermeture, lecture/criture). L'unit d'information gre par un flux est le byte.

Certains de ces flux sont connects des priphriques permettant par exemple de raliser une interface entre la machine et l'utilisateur (IHM) en mode texte. Mais la plupart du temps, le nom associ au flux est en fait un 'fichier', c'est--dire une sorte de mmoire (disque, flash) accessible en criture et en lecture par l'intermdiaire du systme. L'avantage vident est que les donnes sont permanentes, mme aprs mise hors tension de la machine.

En consquence, dans la pratique, les termes flux et fichiers sont souvent confondus.

XXXIII-B. Texte ou binaire ?

Le langage C fait la distinction entre les fichiers binaires et les fichiers textes. Cette distinction est historique. Elle dpend en fait du systme utilis. Sur certains systmes, il n'existe aucune diffrence physique entre les fichiers textes et les fichiers binaires. Sur d'autres systmes, il existe une diffrence. Par souci de portabilit, il est recommand de respecter cette distinction.

Le choix entre fichier texte ou binaire provient du contenu de ce fichier.

XXXIII-B-1. Fichier texte

On appelle fichier texte un fichier qui contient des informations de type texte, c'est dire des squences de lignes.

Une ligne est une squence de caractres imprimables termine par une marque de fin de ligne.

Selon le systme, la marque de fin de ligne est compose de un ou plusieurs caractres de contrle (par exemple, CR, LF, ou une squence de ces caractres)

 
Sélectionnez
:----------------:--------------:----------------:
: Systme        : Fin de ligne : Fin de fichier :
:----------------:--------------:----------------:
: Unix           :              :                :
: Mac X          : 0x0A LF      : Sans objet     :
: Linux          :              :                :
:----------------:--------------:----------------:
: Mac (non unix) : 0x0D CR      : Sans objet     :
:----------------:--------------:----------------:
: MS-DOS         : 0x0D CR      : 0x1A           :
: Windows        : 0x0A LF      : ^Z             :
: Windows NT     :              :                :
:----------------:--------------:----------------:
: VMS STREAM_CR  : 0x0D CR      : Sans objet     :
:----------------:--------------:----------------:
: VMS STREAM_LF  : 0x0A LF      : Sans objet     :
:----------------:--------------:----------------:
: VMS STREAM_CRLF: 0x0D CR      : Sans objet     :
:                : 0x0A LF      :                :
:----------------:--------------:----------------:

L'ensemble des valeurs numriques des caractres (charset) dpend du systme. La plupart du temps, il s'agit du codage ASCII (0-127) avec des extensions plus ou moins standards au del de 127. Il existe d'autres codes, comme EBCDIC utilis sur certains mainframes IBM.

Pour crire une fin de ligne dans un fichier texte, il suffit d'crire le caractre '\n'. Celui-ci sera alors automatiquement traduit en marqueur de fin de ligne.

De mme, lors de la lecture d'un fichier texte, le marqueur de fin de ligne est automatiquement traduit en '\n', quel qu'il soit.

Nota : Certains systmes marquent la fin des fichiers textes d'un caractre spcial. Par exemple MS-DOS ajoute un code 26 (^Z). Cela signifie que, pour ce systme, la lecture d'un fichier texte s'arrte ds la rencontre de ce caractre.

XXXIII-B-2. Fichier binaire

N'importe quel fichier, y compris un fichier texte, peut tre considr comme binaire. Dans ce cas, l'criture et la lecture des caractres se fait sans interprtation.

Par exemple, sur une plateforme utilisant le jeu de caractres ASCII, CR vaut 13 ou 0x0D ou '\r'. De mme, LF vaut 10 ou 0x0A ou '\n'.

XXXIII-B-3. Modes d'ouverture d'un fichier

La fonction d'ouverture de fichier est fopen(). Comme pour les autres fonctions de gestion des fichiers, le fichier d'interface est <stdio.h>.

 
Sélectionnez
FILE *fopen (char const *filename, char const *mode);

Le mode d'ouverture est dtermin par une chaine de caractre. Voici les chanes correspondant aux principaux modes :

 
Sélectionnez
   "r"  : mode texte en lecture
   "w"  : mode texte en criture (cration)
   "a"  : mode texte en criture (ajout)
 
   "rb" : mode binaire en lecture
   "wb" : mode binaire en criture (cration)
   "ab" : mode binaire en criture (ajout)

XXXIII-B-4. Lecture d'un fichier

Le langage C offre plusieurs fonctions permettant de lire les donnes d'un fichier.

  • fgetc()
  • getc()
  • fread()
  • fscanf()
  • fgets()
XXXIII-B-4-a. fgetc(), getc()

Ces fonctions sont identiques. Elles permettent de lire un caractre.

XXXIII-B-4-b. fread()

Cette fonction permet de lire un bloc de caractres d'une longueur donne. Elle est tout fait adapte la lecture des donnes binaires brutes (non interprtes).

XXXIII-B-4-c. fscanf()

Cette fonction permet de lire des donnes 'texte' formates. Cette fonction est d'une utilisation complexe et son usage est peu recommand.

XXXIII-B-4-d. fgets()

Cette fonction permet de lire une ligne de texte. Elle est tout fait adapte la lecture d'un fichier texte ligne par ligne.

Sa simplicit d'utilisation et sa robustesse en font la fonction prfre des programmeurs qui doivent analyser des fichiers textes.

XXXIII-B-4-d-i. Exemple d'utilisation

Soit le fichier texte :

 
Sélectionnez
Ceci est un simple fichier
texte de 2 lignes.

et un petit programme permettant de lire ces 2 lignes

 
Sélectionnez
/* fichier1.c */
#include <stdio.h>
 
int main (void)
{
   /* ouverture du fichier en mode texte */
   FILE *fp = fopen ("data.txt", "r");
 
   /* L'ouverture du fichier est-elle realisee ? */
   if (fp != NULL)
   {
      /* definition d'un tableau de char destine a recevoir la ligne
       * La taille est arbitraire. Elle doit etre cependant adaptee * aux besoins courants.
       * Pour les grandes tailles (disons > 256 char),
       * il est preferable d'utiliser une allocation dynamique.
       */
      char ligne[32];
 
      /* lecture de la premiere ligne */
      fgets (ligne, sizeof ligne, fp);
 
      /* Affichage de la premiere ligne */
      printf ("1: %s\n", ligne);
 
      /* lecture de la deuxieme ligne */
      fgets (ligne, sizeof ligne, fp);
 
      /* Affichage de la deuxieme ligne */
      printf ("2: %s\n", ligne);
 
      /* Fermeture du fichier */
      fclose (fp);
   }
   else
   {
      printf ("Erreur d'ouverture du fichier\n");
   }
   return 0;
}
   

On doit obtenir ceci sur la sortie standard (stdout):

 
Sélectionnez
1: Ceci est un simple fichier
 
2: texte de 2 lignes.
XXXIII-B-4-d-ii. Explication

La ligne lue est stocke dans la variable ligne, y compris le '\n'. La fonction d'affichage printf() affiche le numro de ligne, suivit de ': ', la ligne (avec son '\n') et un '\n' en plus, ce qui explique la prsence de lignes "vides".

XXXIII-B-4-d-iii. Critique de cet exemple

Cet exemple de codage 'naf' souffre d'un dfaut majeur : Il fait l'hypothse que le fichier fait 2 lignes, et il continue lire le fichier mme si une erreur de lecture s'est produite. En fait, tout simplement, il ne gre pas les erreurs de lecture.

Il est facile de grer les erreurs de lecture. Toutes les fonctions de lecture retournent une valeur. Celle-ci peut prendre une valeur particulire qui signifie 'Arrt de la lecture'. La cause n'est pas prcise. a peut tre cause d'une erreur (support en panne, donnes corrompu, fichier inexistant etc.) ou tout simplement par ce que la fin de fichier a t atteinte.

XXXIII-B-4-d-iv. Dtection d'une erreur

La fonction fgets() retourne une valeur de type char *. Si la lecture a russi, la valeur retourne est l'adresse du tableau de char pass en paramtre. En cas d'chec, la valeur NULL est retourne. Il suffit donc de surveiller cette valeur pour savoir si on peut continuer ou non. Comme une des causes d'chec est la "fin de fichier atteinte", on peut donc parfaitement intgrer ce test dans une boucle de lecture "ligne par ligne".

Une fois l'chec de la lecture constat, il est possible d'en identifier la cause. Le langage C met disposition les deux fonctions feof() et ferror() qu'il faut appeler aprs la boucle de lecture, mais avant la fermeture du fichier.

 
Sélectionnez
     while (fonction_de_lecture(fp) != ERREUR)
   {
      ...
   }
 
   if (feof(fp))
   {
      /* la fin de fichier a ete detectee */
      puts ("EOF");
   }
 
   if (ferror(fp))
   {
      /* une erreur s'est produite */
      perror (NOM_DU_FICHIER);
   }
 
   fclose (fp);
XXXIII-B-4-d-v. Gestion des fins de ligne

On constate que lorsque fgets() lit une ligne entire, un '\n' se retrouve la fin de la chaine saisie. La prsence de '\n' est gnante ou non selon l'application.

Ceci dit, dans tous les cas, il est conseill d'en dtecter la prsence. En effet, sa prsence indique que la ligne a t lue entirement, alors que son absence indique que la ligne a t tronque, et que d'autres caractres (au minimum un '\n') attendent pour tre lus. Il est donc conseill d'crire ces quelques lignes aprs un fgets() pour clarifier la situation :

 
Sélectionnez
#include <stdio.h>
#include <string.h>
   ...
{
   char ligne[123];
 
   /* test d'erreur omis */
   fgets (ligne, sizeof ligne, fp);
 
   {
      /* chercher le '\n' */
      char *p = strchr(ligne, '\n');
 
      if (p != NULL)
      {
         /* si on l'a trouve, on l'elimine. */
         *p = 0;
      }
      else
      {
         /* Le traitement depend de l'application.
          * Par exemple, ici, on choisi d'ignorer
          * les autres caracteres.
          */
 
         /* sinon, on lit tous les caracteres restants */
         int c;
 
         while ((c = fgetc(fp)) != '\n' && c != EOF)
         {
         }
      }
   }
}

Il est clair que dans la pratique, l'ensemble de ce code devra tre intgr dans une fonction unique de lecture d'une ligne partir d'un flux.

XXXIII-B-4-d-vi. Exemple amlior avec dtection de la fin de lecture
 
Sélectionnez
/* fichier2.c */
#include <stdio.h>
 
int main (void)
{
   FILE *fp = fopen ("data.txt", "r");
 
   if (fp != NULL)
   {
      char ligne[32];
 
      /* definition d'un compteur de lignes et initialisation */
      int cpt = 0;
 
      /* lecture des lignes */
      while (fgets (ligne, sizeof ligne, fp) != NULL)
      {
         /* Mise a jour du compteur */
         cpt++;
 
         /* Affichage des lignes */
         printf ("%d: %s\n", cpt, ligne);
      }
 
      /* On peut ajouter ici la detection de la cause
       * de l'erreur decrite ci-dessus
       */
 
      fclose (fp);
   }
   else
   {
      printf ("Erreur d'ouverture du fichier\n");
   }
 
   return 0;
}

Cet exemple met en oeuvre un mcanisme qui s'adapte automatiquement au nombre de lignes du fichier. Cependant, attention, le fonctionnement, bien qu'il reste sr, risque d'tre surprenant si la longueur de la ligne est suprieure celle du tableau 'ligne'.

Par exemple, si on diminue la taille de 'ligne' 16 au lieu de 32,

 
Sélectionnez
<...>
   char ligne[16];
<...>
  

on obtient :

 
Sélectionnez
1: Ceci est un sim
2: ple fichier
 
3: texte de 2 lign
4: es.
  
XXXIII-B-4-d-vii. Explication

Rappelons que la taille du tableau de char a t transmise la fonction fgets().

Celle-ci tente de lire la ligne, mais celle-ci est trop longue pour tenir dans le variable 'ligne'. fgets(), qui connat la taille de la variable 'ligne', applique alors une stratgie d'adaptation qui consiste stocker ce qui est possible dans la variable, en laissant une place pour le 0 final. En effet, fgets() a pour obligation de produire une chaine de caractres valide dans tous les cas.

C'est pourquoi la premire ligne est partiellement lue ainsi :

 
Sélectionnez
0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 : Indice
'C' 'e' 'c' 'i' ' ' 'e' 's' 't' ' ' 'u' 'n' ' ' 's' 'i' 'm'  0 : Donnes

Mais les caractres manquants ne sont pas perdus, et ils sont lus par l'appel suivant:

 
Sélectionnez
0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 : Indice
'p' 'l' 'e' ' ' 'f' 'i' 'c' 'h' 'i' 'e' 'r' '\n' 0             : Donnes
  

Cette fois, la place est suffisante, et l'ensemble de la chaine est lue, y compris le '\n'.

XXXIII-B-5. criture dans un fichier

Le langage C offre plusieurs fonctions permettant d'crire des donnes dans un fichier.

  • fputc()
  • putc()
  • fwrite()
  • fprintf()
  • fputs()
XXXIII-B-5-a. fputc(), putc()

Ces fonctions sont identiques. Elles permettent d'crire un caractre.

XXXIII-B-5-b. fwrite()

Cette fonction permet d'crire un bloc de caractres d'une longueur donne. Elle est tout fait adapte l'criture de donnes binaires brutes (non interprtes).

XXXIII-B-5-c. fprintf()

Cette fonction permet d'crire des donnes 'texte' formates. Elle comporte de nombreuses possibilits de conversion de valeurs numriques en texte. (Entiers, flottants etc.)

XXXIII-B-5-d. fputs()

Cette fonction permet d'crire une chaine de caractres.

XXXIII-B-6. Bien utiliser les formats de donnes

Il n'est pas rare que des donnes enregistres dans un fichier par une machine soient lues par une autre machine, ou par autre programme ou par le mme programme mais compil avec des options diffrentes. Pour pouvoir rcuprer les donnes, il faut qu'en aucun cas, le format des donnes enregistres ne dpende de l'implmentation.

XXXIII-B-6-a. Format orient texte

Le format texte est un bon choix, car il utilise une squence de caractres simple et vidente (chronologique) et un codage trs rpandu (ASCII). Il peut y avoir quelques problmes de transcodage pour les valeurs de 128 255 (ANSI, OEM etc.), mais rien qui ne soit insurmontable. D'autre part, la conversion ASCII/EBCDIC est triviale.

Il subsiste le problme des fins de ligne qui sont diffrentes d'un systme l'autre. Il existe des utilitaires bien connus (dos2unix, unix2dos etc.) gnralement fournis avec ces systmes qui font les conversions. Rappelons que la fonction system() permet d'appeler une commande extrieure. Si nanmoins, cet utilitaire n'existait pas, il serait facile de le faire soi-mme. Bien sr, il faudrait travailler en mode binaire de faon contrler les donnes du fichier de manire 'brute' (raw).

Les chanes et les valeurs numriques sont encodes et ventuellement formates avec fprintf(). Une organisation en ligne est souhaitable. Elles sont ensuite lues ligne par ligne avec fgets() et analyses soit par strtol(), strtoul() ou strtod() pour les cas les plus simples (valeurs numriques pures), soit par sscanf() pour les cas plus complexes, condition que le formatage soit clairement dfini. Il est souhaitable d'utiliser des formats simples analyser et surtout sans ambigut quant aux sparateurs. Le format CSV est recommand.

XXXIII-B-6-b. Format orient binaire

Une mauvaise utilisation des formats binaires (raw) peut apporter des problmes de portabilit. Il est recommand d'utiliser des formats indpendants comme XDR (RFC 1832).

XXXIII-C. Supprimer un enregistrement dans un fichier binaire

Pour supprimer un enregistrement, le plus simple est de procder ainsi:

  • Le fichier original est ouvert en lecture. Un nouveau fichier est ouvert en criture. L'original est lu enregistrement par enregistrement (fread()), et recopi dans le nouveau fichier (fwrite()) en omettant l'enregistrement supprimer (if ...).
  • Par un jeu subtil de suppression et de renommage (remove(), rename()), on se retrouve avec une copie de l'original (genre .old ou .bak) et le nouveau fichier qui a maintenant le nom de l'ancien. L'opration reste simple, et a l'avantage de permettre l'annulation (par renommage de l'ancien fichier).

Toute autre opration base sur l'criture/lecture dans le mme fichier est dangereuse, non portable et se traduit souvent par la destruction du fichier original sans recours possible.

XXXIII-D. En guise de conclusion

Il ne faut pas se tromper d'outil. Les flux du C sur disque sont trs pratiques pour enregistrer quelques donnes statiques dans un fichier texte. En binaire, c'est dj plus risqu moins de passer par un format indpendant comme XDR. Pour grer des enregistrements, les fichiers C sont trop rustiques. Il faut une vritable base de donnes (comme SQLite ou MySQL par exemple).

XXXIV. Pourquoi fflush (stdout) ?

Il arrive parfois de rencontrer ce genre de code ...

 
Sélectionnez

printf("Entrez un nombre : ");
fflush (stdout);

... et on se demande alors quoi peut bien servir ce fflush (stdout).

Le printf() prcdent envoie une chaine de caractres stdout. Or cette chaine n'est pas termine par un '\n'.

Il faut savoir que stdout est souvent un flux "bufferis", ce qui signifie, en bon franais, que les caractres sont placs dans un tampon (buffer) de sortie avant d'tre rellement mis.

Il y a trois critres qui dclenchent l'mission relle des caractres :

  • Le tampon d'mission est plein (incontrlable)
  • Un '\n' a t plac dans le tampon[1]
  • La commande de forage a t active

La commande de forage est active par l'appel de la fonction fflush (stdout), ce qui explique sa prsence dans le code mentionn.

[1] sauf en cas de redirection dudit flux vers un fichier.


prcdentsommairesuivant

Copyright © 2009 Emmanuel Delahaye. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.