1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| // lire_chaine.c
#include <stdlib.h>
#include <stdio.h>
/* -ed- header inconnu.
#include "lire_chaine.h"
*/
/* -ed- ajoute */
#include <string.h>
/*
lireChaine
Lit une chaine de caractères.
Retourne EXIT_SUCCESS si tout se passe bien
Retourne EXIT_FAILURE si la taille de la chaine saisie est supérieure
à celle de la chaine cible.
Paramètre 1 : la chaine cible
Paramètre 2 : la taille de cette chaine
*/
int lireChaine (char *chaine, long taille)
{
char buffer[300] = { 0 }; // Le buffer qui va recevoir la chaine tappée
char caractereLu = 0; // La variable qui reçoit les caractères un a un
long i = 0; // Pour les boucles
/* Tant qu'on a pas entré de retour à la ligne et tant qu'on ne dépasse
pas la taille de la chaine dans laquelle on veut écrire, on continue
de recevoir les caractères entrants */
/* -ed- beaucoup de problemes ici
i risque d'atteindre taille, ce qui peut provoquer un debordement.
la lecture de stdin s'arrette quand la destination est pleine.
Cela signifie que les caracteres pendants ne sont pas lus. Qui va les
lire ? Le prochaine appel de fgetc() sera non blocant...
On retombe dans les travers bien connu des fonctions de saisies...
Constatant que le tableau est plein et que le dernier caractere lu n'est
pas '\n', il faudrait envisager une purge des carcteres restants, soit ici,
soit par l'appelant.
Enfin, que se passe-t-il su taille est > sizeof buffer ?
Gros probleme de conception. En fait, ce tableau intermediaire
(qui oblige a faire une copie : strcpy()) est inutile et dangereux.
*/
while ((caractereLu = getchar ()) != '\n' && i <= taille)
{
buffer[i] = caractereLu;
i++;
}
/* Si la taille de la chaine dans laquelle on veut écrire a été dépassée,
on écrit une erreur et on retourne un échec */
if (i - 1 >= taille)
{
fprintf (stderr,
"Erreur : la taille de la chaine saisie depasse celle de la chaine cible.\n");
return EXIT_FAILURE;
}
/* Si on a pas dépassé la taille de la chaine dans laquelle on veut écrire,
on ajoute le caractere NULL au buffer et on copie vers la chaine */
buffer[i] = '\0';
/* -ed- pas de prototype */
strcpy (chaine, buffer);
/* Tout s'est bien passé, on retourne EXIT_SUCCESS */
return EXIT_SUCCESS;
}
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
char chaine[20] = { 0 };
printf ("Entrez une chaine : ");
fflush (stdout);
/* -ed-
if (lireChaine(chaine, 20) == EXIT_SUCCESS)
toujours preferer le code 'auto-demerdant' */
if (lireChaine (chaine, sizeof chaine) == EXIT_SUCCESS)
{
printf ("La chaine est : \"%s\" et contient %d caracteres", chaine,
strlen (chaine));
}
return EXIT_SUCCESS;
}
#endif |
Partager