« Programmation C/Entrées/sorties » : différence entre les versions

Contenu supprimé Contenu ajouté
Thierry46 (discussion | contributions)
Thierry46 (discussion | contributions)
→‎Entrées non formatées : Suppression exemple erronné et lien sur livre d'exercice pour une solution.
Ligne 469 :
</source>
 
La fonction <code>fgets()</code> permet de saisir une ligne complète dans la zone mémoire spécifiée, en évitant tout débordement. Si la ligne peut être contenue dans le bloc, elle contiendra le caractère de saut de ligne (<code>'\n'</code>), en plus du caractère nul. Dans le cas contraire, la ligne sera tronquée, et la suite de la ligne sera obtenue à l'appel suivant. Si la fonction a pu lire au moins un caractère, elle retournera la chaine transmise en premier argument, ou <code>NULL</code> s'il n'y a plus rien à lire. Un exemple de lecture de ligne arbitrairement longue est vu plus bas.
 
Un exemple de lecture de ligne arbitrairement longue est fournie dans le livre [[Exercices en langage C/Fonctions#Lire une ligne longue avec fgets|Exercices en langage C]] (énnoncé et solution).
La fonction <code>fgetc()</code> permet de ne saisir qu'un caractère depuis le flux spécifié. À noter que la fonction renvoie bien un entier de type <code>int</code> et non de type <code>char</code>, car en cas d'erreur (y compris la fin de fichier), cette fonction renvoie <code>EOF</code> (défini à -1 en général).
 
<source lang="c">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
 
/**
* lire_ligne tente de lire une ligne entiere depuis le flux.
* Le '\n' final est enlevé.
*
* Si la ligne est vide, la fonction renvoie un pointeur vers
* une chaîne contenant uniquement '\0' et place errno à 0.
*
* Si une erreur intervient au début de la lecture,
* la fonction renvoie NULL et place errno à 1.
*
* Si une erreur intervient après qu'au moins un caractère a été lu,
* la fonction renvoie ce qui a été lu, et place errno à 1.
*
* En cas de succès, errno est placé à 0.
*/
char *lire_ligne(FILE *flux)
{
int taille = 256;
char *chaine = malloc(taille);
errno = (chaine == NULL);
if (chaine != NULL)
{
int i = 0;
int c;
while ((c = fgetc(stdin)) != EOF)
{
if (i == taille)
{
/* Le tableau est plein, et on a encore des choses a lire... */
taille += 256;
char *nouvelle = realloc(chaine, taille);
if (nouvelle == NULL)
{
errno = 1;
break;
}
chaine = nouvelle;
}
if (c != '\n')
{
chaine[i] = c;
i++;
}
else
{
/* fin de la ligne: on s'arrete sans mettre le '\n' */
break;
}
}
chaine[i] = '\0';
}
return chaine;
}
</source>
 
À noter que cette fonction est incapable de traiter des fichiers mixtes (binaire et texte) depuis un descripteur en mode caractère (accès séquentiel). D'une part la fonction ne renvoyant pas le nombre d'octets lus (ce qui aurait facilement réglé le problème) et d'autre part, ftell() ne fonctionnant pas sur de tels descripteurs, il faudra reprogrammer <code>fgets</code> pour gérer ce cas de figure.