Bonjour

Ça fait maintenant un bon bout de temps que je ne fréquente plus le forum C.
Je viens de recevoir un mp au sujet d'une contribution que j'avais écrite sur la réallocation du buffer de saisie à la volée.
Ne l'ayant plus et ne la trouvant pas sur le site, j'ai tenté de la réécrire et je viens la poster ici pour deux raisons :
  • savoir si elle est correcte
  • que le po ne s'approprie pas la réponse et que tout le monde puise la partager (si elle est correcte bien entendu)

Voici le code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
// fonction de lecture de lignes d'un fichier ouver en mode texte
int lecture(FILE *f)
{
	// longueur initiale du buffer de lecture
	// on peut choisir une autre valeur bien entendu !
	size_t len = 10;
	size_t old_len = len;
	// le meilleur facteur d'accroissement de longueur est le nombre d'or !
	// le nombre d'or = 1,61803399
	double incr = 1.62;
	char *ptr;
	int flag = 0 ; // 0 si la lecture a été complète, 1 sinon
 
	// initialisation du buffer de saisie
	ptr = malloc(len);
 
	// toujours tester le retour du malloc
	if (ptr == NULL)
	{
		fprintf(stderr, "Pb alloc memoire \n");
		return 0;
	}
 
	while(fgets(ptr + (flag > 0) * old_len - flag , len - (flag  > 0) * old_len, f) != NULL)
	{
		// on teste si la saisie est complète
		char *p = strchr(ptr, '\n') ;
		if (p == NULL)
		{
			// saisie incomplète
			char *tmp ;
 
			old_len = len;
			len = (size_t) (incr * len);
 
			tmp = realloc(ptr, len);
			if (tmp == NULL)
			{
				// l'allocation a echoue, on ne peut rien faire
				fprintf(stderr, "Pb alloc memoire \n");
				return 0;
			}
			else
				ptr = tmp;
			flag ++;
		}
		else
		{
			*p = 0;
			flag = 0;
 
			// ici on peut travaille sur la saisie complète
			// simple affichage 
 		        puts(ptr);
		}
	}
	free(ptr);
	return 1;
}
J'avoue que j'ai un problème sur le fgets, je ne sais pas bien expliquer pourquoi il faut écrire (ptr + (flag > 0) * old_len - flag , si on passe plusieurs fois dans une lecture incomplète, flag comptant le nombre de lecture incomplètes consécutives.

merci de vos remarques éventuelles.