Lire un fichier texte ligne par ligne
Date de publication : 1-07-08
Par
Patrick Gonord
Ce module permet la lecture d'un fichier texte ligne par ligne.
Il réalise l'allocation dynamique nécessaire au stockage de la ligne.
La taille d'une ligne est uniquement limitée par la mémoire disponible.
I. Présentation
II. Code source
III. Code exemple
I. Présentation
Une des difficultés rencontrées lors de la lecture des lignes d'un fichier
est de prévoir la longueur maximale que peut avoir une ligne pour dimensionner
correctement le buffer de réception. Cette fonction réalise les allocations
nécessaires.
Ses caractéristiques principales sont :
- Chaque ligne est terminée par '\n' ou par la fin du fichier.
- La fonction réalise l'allocation du buffer nécessaire au
stockage de la ligne.
- Le caractère de fin de ligne n'est pas stocké dans le buffer.
- Elle renvoie le nombre de caractères placés dans le buffer
(sans compter le '\0' de fin de chaîne).
- Elle indique les erreurs d'allocations et la fin de fichier.
Le prototype de cette fonction est :
Prototype |
long LireLigne (FILE * f, char * * buff, long dim);
|
- f est un pointeur sur un fichier texte déjà correctement ouvert.
- buff est l'adresse d'un pointeur sur char qui recevra l'adresse
du buffer créé par la fonction et contenant la ligne lue.
- Si à l'appel de la fonction *buff est différent de NULL, il est considéré
comme contenant l'adresse d'un buffer précédemment créé par la fonction
et la fonction procède à la libération de cet espace mémoire avant de
lire la ligne suivante.
Lors du premier appel, *buff doit alors être mis à NULL
Si le fichier n'est pas entièrement lu, il est de la responsabilité du programmeur
de libérer la mémoire contenant la dernière ligne lue.
- En sortie de la fonction, *buff contiendra l'adresse du buffer contenant
la ligne lue.
*buff==NULL indique la fin du fichier ou une erreur d'allocation mémoire.
- dim est le nombre de bytes alloués initialement par la fonction
pour le buffer devant contenir la ligne. Le buffer sera redimensionné
en fonction de la longueur de la ligne. Si dim est inférieur à 2, la
dimension initiale sera prise comme la valeur de la macro DIM_DEFAULT
- En retour :
- la fonction renvoie le nombre de caractères placés dans le buffer
(le caractère '\0' n'est pas compté).
- Si la ligne est vide, la valeur de retour est 0 et le buffer ne contient que '\0'.
- En cas de fin de fichier, la valeur de retour est 0 et *buff est placé à NULL.
- En cas d'erreur d'allocation, la valeur de retour est -1
Pour résumer :
Valeur de retour |
-1 |
0 |
>0 |
*buff == NULL |
Erreur d'allocation |
Fin de fichier |
X |
*buff != NULL |
X |
Ligne vide |
Nombre de caractères |
II. Code source
Le fichier d'en tête (LireLigne.h):
# ifndef LireLigne_H
# define LireLigne_H
# include <stdio.h>
# define DIM_DEFAULT 32
long LireLigne (FILE * f, char * * buff, long dim);
# endif
|
Le fichier source (LireLigne.c):
# include <string.h>
# include <stdlib.h>
# include "LireLigne.h"
static long Cherchecar (char * buffer, long offset, int car)
{
char * pos = strchr (buffer+ offset,car);
return pos ! = NULL ? pos - buffer : - 1 ;
}
static char * RedimAlloc ( char * buffer, size_t dim)
{
char * q = realloc (buffer,dim);
if (q = = NULL ) free (buffer);
return q;
}
long LireLigne (FILE * f, char * * buff, long dim)
{
long eoln = - 1 ;
long zero = - 1 ;
char * notEOF;
int AllocError;
long offset = 0 ;
free (* buff);
if (dim< 2 ) dim = DIM_DEFAULT;
* buff = malloc ((size_t)dim);
AllocError = * buff = = NULL ;
if (! AllocError)
{
notEOF= fgets (* buff,dim,f);
if (! notEOF)
{
free (* buff);
* buff = NULL ;
}
while (notEOF & & eoln < 0 & & * buff ! = NULL )
{
eoln = Cherchecar (* buff,offset,' \n ' );
if (eoln >= 0 ) (* buff)[eoln] = ' \0 ' ;
else
{
zero = Cherchecar (* buff,offset,' \0 ' );
if (zero = = dim- 1 )
{
offset = dim- 1 ;
dim * = 2 ;
* buff = RedimAlloc (* buff,(size_t)dim);
AllocError = * buff = = NULL ;
}
if (! AllocError)
if (! (notEOF = fgets (* buff+ offset,offset+ 2 ,f))) eoln = zero;
}
}
if (* buff! = NULL ) * buff = RedimAlloc (* buff,(size_t)(eoln+ 1 ));
}
return * buff ! = NULL ? eoln
: AllocError ? - 1 : 0 ;
}
|
III. Code exemple
Voici un exemple d'utilisation de ce code :
# include <stdlib.h>
# include <stdio.h>
# include "LireLigne.h"
int main (void )
{
char * buff = NULL ;
long nb;
FILE * f;
f = fopen (" LireLigne.txt " ," r " );
if (f! = NULL )
{
do
{
nb = LireLigne (f,& buff,5 );
if (buff! = NULL ) printf (" <%s> nb = %ld\n " , buff,nb);
}
while (buff! = NULL );
printf (nb < 0 ? " Erreur d'allocation\n " : " Fin de fichier\n " );
}
else printf (" \n fichier non trouve " );
return EXIT_SUCCESS;
}
|
Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
2009 Developpez. 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. Droits de diffusion permanents accordés à Developpez LLC.