« Exercices en langage C/Fonctions » : différence entre les versions

Contenu supprimé Contenu ajouté
Thierry46 (discussion | contributions)
→‎Les fonctions : Exercice lire_ligne (début)
Thierry46 (discussion | contributions)
Ligne 23 :
<div style="width:70%">{{Boîte déroulante|titre=lire_ligne.c à compléter|contenu =
<source lang="c">
/**
* Fonction .. : lire_ligne
* Role ...... : tente de lire une ligne entiere depuis le flux.
* - Le caractere de saut de ligne '\n' final est enleve.
* - L'appellant doit se charger de la desallocation de la chaine retournee.
*
* Parametres :
* - pChaine : adresse de retour de la chaine
* - tailleBufferLecture : taille du buffer de lecture,
* dans la pratique on pourra choisir _POSIX_MAX_INPUT (ref limits.h).
* - flux : un pointeur sur le descripteur du fichier a lire.
*
* - Valeur retournee :
* - Si OK : EXIT_SUCCESS.
* - Si Fin de fichier atteinte sans rencontrer \n : EOF,
* - la chaine retournée contient le debut de la ligne longue.
* - Si rien a lire, retour d'un pointeur NULL pour la chaine.
* - En cas de probleme : Le code d'erreur systeme utilisable par perror.
* et retour d'un pointeur NULL pour la chaine.
*
* Auteur ...... : Votre nom
* Version ..... : 1.0 du date
* Licence ..... : GNU GPL.
lire_ligne : Lecture d'une ligne longue dans un fichier texte
Copyright (C) 2008 Thierry46
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Compilation . : gcc -pedantic -Wall -std=c99 -c lire_ligne.c
* Fichiers lies : main_lire_ligne.c, lire_ligne.h
*
* Remarque :
* Beaucoup de commentaires sont présents pour un usage didactique.
* Ce programme utilise une syntaxe specifique C99.
* Ce programme a ete controle avec l'outil de verification statique
* Splint v3.1.2 du 19 Jan 2008 : http://www.splint.org/
*/
#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)
{
// Début partie à compléter...
// Fin partie à compléter...
} // char *lire_ligne(...
</source>
}} </div>
Ligne 28 ⟶ 90 :
<div style="width:70%">{{Boîte déroulante|titre=lire_ligne.h|contenu =
<source lang="c">
/*
* Nom .... : lire_ligne.h
* Role ... : Definitions et prototype de lire_ligne.h
* Auteur ...... : Thierry46
* Version ..... : 1.0 du 30/1/2008
* Licence ..... : GNU GPL.
lire_ligne : Lecture d'une ligne longue dans un fichier texte
Copyright (C) 2008 Thierry46
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Fichier lie : lire_ligne.c
*/
#ifndef LIRE_LIGNE_H
#define LIRE_LIGNE_H
 
extern /*@null@*/ char *lire_ligne(size_t tailleBufferLecture,
FILE * restrict flux, int *pCodeRetour);
 
#endif
</source>
}} </div>
Ligne 33 ⟶ 126 :
<div style="width:70%">{{Boîte déroulante|titre=main_lire_ligne.c|contenu =
<source lang="c">
/*
* Nom ......... : main_lire_ligne.c
* Role ........ : Tester la fonction lire_ligne
* Parametre ... : Aucun
* Code retour . : EXIT_SUCESS (0)
* Auteur ...... : Thierry46
* Version ..... : 1.0 du 30/1/2008
* Licence ..... : GNU GPL.
lire_ligne : Lecture d'une ligne longue dans un fichier texte
Copyright (C) 2008 Thierry46
 
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Compilation . :
* Voir lire_ligne .c pour sa compilation
* gcc -pedantic -Wall -std=c99 -o test_lire_ligne.exe main_lire_ligne.c lire_ligne.o
* Exécution : ./test_lire_ligne.exe
* Fichiers lies : lire_ligne.c, lire_ligne.h, test_lire_ligne.txt
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lire_ligne.h"
 
#define FIC_TEST "test_lire_ligne.txt"
// Valeur faible de TAILLE_BUFFER pour test débordements et lecture multiple.
#define TAILLE_BUFFER (size_t)10
#define TAILLE_MAX_MESSAGE 256
 
int main(void)
{
FILE *hFicTest = NULL;
char *chaine = NULL;
int numLigne = 1;
int retour = EXIT_SUCCESS;
char message[TAILLE_MAX_MESSAGE];
hFicTest = fopen(FIC_TEST, "r");
if (hFicTest == NULL)
{
(void)printf("%s : le fichier %s n'a pas pu etre ouvert !\n",
__func__, FIC_TEST);
// Je laisse poursuivre pour tester assertion dans lire_ligne. //
}
do
{
chaine = lire_ligne(TAILLE_BUFFER, hFicTest, &retour);
if (retour == EXIT_SUCCESS)
{
(void)strncpy(message, "Pas d'erreur", sizeof(message) - 1);
}
else if (retour == EOF)
{
(void)strncpy(message, "Fin de fichier", sizeof(message) - 1);
}
else
{
(void)strncpy(message, strerror(retour), sizeof(message) - 1);
}
message[sizeof(message) - 1] = '\0';
(void)printf("Ligne %d : retour = %d (%s), chaine lue = \"%s\".\n",
numLigne, retour, message,
(chaine == NULL) ? "! Pointeur NULL !" : chaine);
 
if (chaine != NULL)
{
free(chaine);
chaine = NULL;
}
} while (retour == EXIT_SUCCESS);
if (hFicTest != NULL)
{
(void)fclose(hFicTest);
}
return EXIT_SUCCESS;
} // int main(void)
</source>
}} </div>
 
<div style="width:70%">{{Boîte déroulante|titre=test test_lire_ligne.txt|contenu =
<pre>
<source lang="c">
1
</source>
1234567880
ligne longue.
 
12345678901234567890123456789012345678901234567890
fin
</pre>
}} </div>