Developpez.com - C
X

Choisissez d'abord la catégorieensuite la rubrique :


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.

       Version PDF (Miroir)   Version hors-ligne (Miroir)
Viadeo Twitter Facebook Share on Google+        



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 :

Le prototype de cette fonction est :
Prototype
long LireLigne(FILE * f, char ** buff, long dim);
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);
/*
 - Lecture d'une ligne sur un fichier texte. la ligne peut être terminée par
   une fin de ligne ou la fin de fichier.
   La fonction alloue la quantité suffisante de mémoire pour stocker la ligne
   et le zéro terminal. Le caractère de fin de ligne, si il existe, n'est pas stocké.

   - f    : Fichier texte ouvert sur lequel est lue la ligne
   - buff : Adresse du pointeur dans lequel sera placée l'adresse de la chaîne obtenue.
            Le pointeur doit contenir l'adresse de la chaîne obtenue lors de l'appel
            précédent à la fonction (pour libération de la mémoire allouée) ou NULL
            si il s'agit du premier appel.
            Le pointeur est mis à NULL et la mémoire libérée si
                - la mémoire disponible est insuffisante
                - la fin du fichier est atteinte.
   - dim  : Nombre de bytes alloués initialement pour stocker la ligne.
            Si dim >2 , une valeur par défaut (DIM_DEFAULT) est utilisée.
            La taille allouée sera augmentée d'un facteur 2 tant que nécessaire
            puis ramenée finalement à la taille  de la ligne.

   - Renvoie le nombre de caractères de la chaîne. le zéro terminal n'est pas compté
            En cas de fin de fichier renvoie 0 (et *Buff == NULL)
            En cas d'erreur d'allocation mémoire renvoie -1 (et *Buff == NULL)
            Pour une ligne vide renvoie 0 (et *Buff != NULL pointe sur '\0')
*/
#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;
}


               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

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 et 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.

Contacter le responsable de la rubrique C