/* Laboratoire 13 (Fichiers) Question 3: Écrire une fonction qui prend en paramètre le nom d'un fichier texte et qui retourne, dans une chaine de caractères allouée dynamiquement, le contenu complet du fichier lu. */ #define _CRT_SECURE_NO_WARNINGS #include #include #include #define TAILLE_MAX_CHAINE 300 //Taille maximale du buffer stockant une chaine de caractères. /* LIRE_FICHIER_TEXTE Fonction qui lit le contenu d'un fichier texte et qui retourne le contenu (intégral) du fichier texte dans une chaine de caractères allouée dynamiquement. NDE: Dans cette solution, nous avons favorisé une allocation entièrement dynamique (il n'y a aucune chaine de caractères allouée de façon statique). Compte tenu qu'on ne connait pas la taille à allouer avant d'avoir lu l'intégralité du fichier (il y'a des façon de faire, mais que nous n'avons pas couvertes dans ce cours), nous faisons l'allocation par blocs. Lorsqu'on atteint le maximum présentement alloué, on agrandit l'espace alloué avec realloc. PARAMÈTRES: - nom_fichier (chaine de caractères): Le nom du fichier à lire. Retour: Chaine de caractère allouée dynamiquement et contenant le contenu intégral du fichier. NULL est retourné en cas d'erreurs. */ char* lire_fichier_texte(char* nom_fichier) { char *resultat; //chaine qui va contenir le contenu du fichier. int taille_max_actuelle=0; //Conserve la taille maximale actuelle de la chaine resultat int nb_chars; //Conserve le nombre de caractères (effectifs) stockés dans resultat char ch; //dernier caractère lu FILE* fichier; //Fichier à lire. //On s'assure d'abord que le fichier peut-être ouvert fichier = fopen(nom_fichier, "r"); if (fichier == NULL) { return NULL; } //On ne connait pas encore la taille du fichier... //On alloue la chaine à une taille initiale //NDE: +1 pour le \0 resultat = (char*)malloc((TAILLE_MAX_CHAINE +1) * sizeof(char)); if (resultat == NULL) { return NULL; } taille_max_actuelle = TAILLE_MAX_CHAINE; nb_chars = 0; //On lit le fichier caractère par caractère jusqu'à atteindre la fin du fichier //fgetc retourne la constante EOF si on a atteint la fin du fichier. while ( (ch = fgetc(fichier)) != EOF ) { //On vérifie qu'on n'a pas excédé la taille maximale if (nb_chars >= taille_max_actuelle) { char *ancienne_adresse; //Adresse temporaire qui servira pour libérer l'espace si //le realloc n'a pas fonctionné ancienne_adresse = resultat; //Si on est dans le if, c'est qu'on a excédé l'espace alloué dynamiquement. //On tente d'augmenter la taille avec un realloc. resultat = (char*)realloc(resultat, (taille_max_actuelle + TAILLE_MAX_CHAINE + 1) * sizeof(char)); if (resultat == NULL) { free(ancienne_adresse); return NULL; } //Ça a fonctionné ==> on garde en mémoire la nouvelle taille maximale. taille_max_actuelle += TAILLE_MAX_CHAINE; } //On stocke le caractère lu resultat[nb_chars] = ch; nb_chars++; } //Terminé avec le fichier, on le ferme. fclose(fichier); resultat[nb_chars] = '\0'; return resultat; } int main(void) { char nom_fichier[TAILLE_MAX_CHAINE]; char* chaine_lue; FILE* fichier; //Handle vers le fichier où on stocke la saisie. //Saisie du nom de fichier à lire printf("Veuillez saisir le nom du fichier: "); fgets(nom_fichier, TAILLE_MAX_CHAINE, stdin); //On ne veut pas de \n dans le nom de fichier, on l'enlève: nom_fichier[strlen(nom_fichier) - 1] = '\0'; chaine_lue = lire_fichier_texte(nom_fichier); if (chaine_lue != NULL) { printf("*** Contenu du fichier: ***\n\n%s", chaine_lue); } else { printf("Une erreur s'est produite lors de la lecture du fichier.\n"); } system("pause"); return EXIT_SUCCESS; }