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
| #define SZ_BUF (100)
#define SZ_ALLOC (1024)
typedef struct {
char *buffer;
char *tmp;
size_t nb_elem;
size_t sz_alloc;
} t_alloc;
int main() {
t_alloc zone;
int nb_lu;
char buffer[SZ_BUF];
...
// On commence par initialiser les éléments important de la zone (notemment ceux qui nous permettent de détecter si on va dépasser)
zone.buffer=NULL;
zone.nb_elem=0;
zone.sz_alloc=0;
// La phase de lecture et de remplissage
while ((nb_lu=read(fd, buffer, SZ_BUF)) > 0) {
// Ici on a un buffer à stocker - On commence par regarder si on a la place de le stocker (ce qui arrive fatalmeent à la première itération puisque tout est à 0)
// Et comme la taille prédéfinie peut ne pas suffire, on est obligé de boucler (ce qui n'est pas nécessaire quand on remplit une zone item par item)
while ((zone.nb_elem + nb_lu) > zone.sz_alloc) {
// Ici on va s'occuper de l'allocation - On commence par augmenter la taille
zone.sz_alloc+=SZ_ALLOC;
// Maintenant on réalloue (si le buffer initial est null, la réallocation se comporte comme une allocation)
zone.tmp=realloc(zone.buffer, zone.sz_alloc * sizeof(char));
// On teste l'allocation
if (zone.tmp == NULL) {
// Allocation échouée - A prévoir un traitement plus malin qu'un bête "exit" de faignasse. A la limite exit() peut se concevoir mais au-moins libérer ce qui avait été précédemment alloué !!!
perror("realloc");
free(zone.buffer);
zone.buffer=NULL;
break;
}
// Allocation réussie - On récupère le pointeur alloué
zone.buffer=zone.tmp;
}
// Si l'allocation a échoué
if (zone.buffer == NULL) break;
// ici on a la place d'écrire dans la zone. On y recopie donc le buffer mais au bon endroit (c'est à dire après ce qui a déjà été écrit auparavant)
memcpy(zone.buffer + zone.nb_elem, buffer, nb_lu);
// On n'oublie pas de comptabiliser ce qui a été stocké
zone.nb_elem+=nb_lu;
}
close(fd);
// Ici le buffer contient tout le fichier (si sa taille le permet bien entendu) - Allez zou, écriture à l'écran
if (zone.buffer)
write(STDOUT_FILENO, zone.buffer, zone.nb_elem);
} |
Partager