fgets
de la bibliothèque standard du langage C permet de lire une chaine de caractère de longueur limitée dans un flux.Vous allez compléter une fonction lire_ligne répondant au spécifications suivantes :
- Retour d'une ligne lue dans un flux texte passé en paramètre.
- Vous éliminerez les caractères de saut de ligne lus.
- La longueur des lignes lues n'est pas limitée.
- Contrôle des paramètres et retour des codes d'erreurs systèmes, détection de la fin du fichier.
- Vous utiliserez au maximum les fonctions de la bibliothèque standard du langage C : allocation mémoire, chaines de caractères...
- Son prototype est donné par lire_ligne.h.
- Vous utiliserez le programme de main_lire_ligne.c pour lire_ligne.
- Vous devrez traiter le fichier test_lire_ligne.txt fourni.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <assert.h> #include <errno.h> #include "lire_ligne.h" /*@null@*/ char *lire_ligne(size_t tailleBufferLecture, FILE * restrict flux, int *pCodeRetour) { // Declarations char *chaineRetour = NULL; bool litEncore = true; bool rienLu = true; int codeRetour = EXIT_SUCCESS; // Controle rapide des parametres. // Si quelque chose ne va pas, arret. assert(tailleBufferLecture > 0); assert(flux != NULL); // On reinitialise errno errno = 0; // Boucle de lecture d'une ligne eventuellement longue do { size_t positionEcriture; char *nouvelleChaine; litEncore = false; // Demande d'une nouvelle zone memoire positionEcriture = (chaineRetour == NULL) ? 0 : strlen(chaineRetour); nouvelleChaine = realloc(chaineRetour, positionEcriture + tailleBufferLecture); if (nouvelleChaine == NULL) // Si probleme d'allocation { codeRetour = errno; free(chaineRetour); chaineRetour = NULL; } else // Si le systeme a accorde la memoire { chaineRetour = nouvelleChaine; if (fgets(chaineRetour+positionEcriture, (int)tailleBufferLecture, flux) != NULL) { // Recherche si un \n a ete lu en fin de chaine. char *positionNewLine = strrchr(chaineRetour, '\n'); rienLu = false; if (positionNewLine != NULL) { // Suppression du caractere de fin de ligne \n, *positionNewLine = '\0'; } else // fgets n'a pas pu lire la ligne complete. { litEncore = true; } } else if (ferror(flux) != 0) { codeRetour = errno; free(chaineRetour); chaineRetour = NULL; } else if (feof(flux) != 0) { codeRetour = EOF; if (rienLu) { free(chaineRetour); chaineRetour = NULL; } } } // else if (nouvelleChaine == NULL) } while (litEncore); // Retour des resultats. *pCodeRetour = codeRetour; return chaineRetour; }
Aucun commentaire:
Enregistrer un commentaire