Dans mes fichiers, les données sont toujours exactement les memes. Donc pour fgets ca ne doit pas poser de problemes pratiques normalement, idem pour sscanf (ceci dit merci d'avoir soulevé le probleme potentiel).
Ca ne pose pas de problèmes, jusqu'à ce que ça en pose... Loi de Murhpy, tu connais ?
fct(&x[100000]) est effectivement faux, mais si je fais fct(x), j'envoie une copie de la structure et non un pointeur non ?
Avec :
#define N 1000
struct T {
int n;
}
void struct g(struct T *p) { /* .... */ }
void f(void)
{
struct T mavar[N];
g(mavar); /* correct */
g(&mavar[0]); /* correct, équivalent à la première ligne */
g(&mavar[N/2]): /* correct aussi */
}
mavar est un tableau de N structures. En C, lorsqu'on passe un tableau en paramètre à une fonction, il est automatiquement converti en un pointeur sur le type de base du tableau, pointant sur le premier élément. Donc, dans le premier appel à g, mavar est converti en struct T*, de valeur &mavar[0]. Les deux premiers appels à g sont donc équivalents. Le troisième est là pour te montrer que tu peux passer un pointeur vers n'importe quel élément du tableau (il faut juste faire attention à bien rester entre les bornes 0 -> N-1). Dans cet exemple, p sera un pointeur vers le 501e élément de mavar.
Note que, dans g, tu peux toujours utiliser la notation tableau sur le pointeur p, pour accéder à d'autres éléments :
#include <stdlib.h>
void struct g(struct T *p)
{
if (p != NULL)
{
/* les trois lignes suivantes sont équivalentes */
printf("a: %d\n", (*p).n);
printf("b: %d\n", p->n);
printf("c: %d\n", p[0].n);
/* la suite suivante ne peut marcher que
* si p pointe dans un tableau, et
* sur autre chose que le dernier élément
*/
printf("d: %d\n", p[1].n);
}
}
Comme on ne peut passer vraiment un tableau en paramètre à une fonction (à cause de la conversion implicite en pointeur), il faut passer à la fonction g la taille du tableau, i.e. le nombre d'éléments accessibles à partir de *p.
void struct g(struct T *p, size_t s)
{
if (p != NULL && s > 0)
{
for (int i = 0; i < s; i++)
{
printf("p[%u].n = %u\n", i, p[i].n);
}
}
}
Ainsi g sait jusqu'où elle peut aller (dans mon exemple, le test "s > 0" est inutile, vue la construction de la boucle, mais dans le cas général il est bon de faire le test).
Pour ton problème, si tu veux avoir un seul tableau pour toutes les données de tous les fichiers, je pense que tu peux faire quelque chose comme ça :
tu créés ton tableau à N éléments par malloc ;
tu passes à ta fonction un pointeur vers le premier élément, la taille N, et le nom du fichier (que tu détermines comme tu veux) ;
la fonction lit ce qui se trouve dans le fichier, à hauteur de N lignes, et les place dans le tableau ;
la fonction renvoie le nombre de lignes lues (avec peut-être un code d'erreur négatif pour indiquer si elle s'est arrêtée à N, et qu'il y a peut-être d'autres lignes encore dans le fichier) ;
la fonction principale reçoit ce nombre de lignes (disons n), puis rappelle la fonction de lecture sur le n+1è élément du tableau, en lui passant N-n comme limite (les erreurs "à un près" sont classiques dans ce genre de travail sur les tableaux, vérifie mes calculs sur le papier avant de coder (et puis c'est toujours un bon exercice)).
Les étapes 2 à 5 sont à faire en boucle, jusqu'à ce que tu ais lu tous tes fichiers.
Je te passe les contrôles d'erreur habituels, c'est juste une idée d'algo que tu peux utiliser, à ajuster en fonction de tes besoins.
[^] # Re: base de la programmation
Posté par alf . En réponse au message Question pour C gourou !. Évalué à 2.
#define N 1000 struct T { int n; } void struct g(struct T *p) { /* .... */ } void f(void) { struct T mavar[N]; g(mavar); /* correct */ g(&mavar[0]); /* correct, équivalent à la première ligne */ g(&mavar[N/2]): /* correct aussi */ }mavar est un tableau de N structures. En C, lorsqu'on passe un tableau en paramètre à une fonction, il est automatiquement converti en un pointeur sur le type de base du tableau, pointant sur le premier élément. Donc, dans le premier appel à g, mavar est converti en struct T*, de valeur &mavar[0]. Les deux premiers appels à g sont donc équivalents. Le troisième est là pour te montrer que tu peux passer un pointeur vers n'importe quel élément du tableau (il faut juste faire attention à bien rester entre les bornes 0 -> N-1). Dans cet exemple, p sera un pointeur vers le 501e élément de mavar. Note que, dans g, tu peux toujours utiliser la notation tableau sur le pointeur p, pour accéder à d'autres éléments :#include <stdlib.h> void struct g(struct T *p) { if (p != NULL) { /* les trois lignes suivantes sont équivalentes */ printf("a: %d\n", (*p).n); printf("b: %d\n", p->n); printf("c: %d\n", p[0].n); /* la suite suivante ne peut marcher que * si p pointe dans un tableau, et * sur autre chose que le dernier élément */ printf("d: %d\n", p[1].n); } }Comme on ne peut passer vraiment un tableau en paramètre à une fonction (à cause de la conversion implicite en pointeur), il faut passer à la fonction g la taille du tableau, i.e. le nombre d'éléments accessibles à partir de *p.void struct g(struct T *p, size_t s) { if (p != NULL && s > 0) { for (int i = 0; i < s; i++) { printf("p[%u].n = %u\n", i, p[i].n); } } }Ainsi g sait jusqu'où elle peut aller (dans mon exemple, le test "s > 0" est inutile, vue la construction de la boucle, mais dans le cas général il est bon de faire le test). Pour ton problème, si tu veux avoir un seul tableau pour toutes les données de tous les fichiers, je pense que tu peux faire quelque chose comme ça :- tu créés ton tableau à N éléments par malloc ;
- tu passes à ta fonction un pointeur vers le premier élément, la taille N, et le nom du fichier (que tu détermines comme tu veux) ;
- la fonction lit ce qui se trouve dans le fichier, à hauteur de N lignes, et les place dans le tableau ;
- la fonction renvoie le nombre de lignes lues (avec peut-être un code d'erreur négatif pour indiquer si elle s'est arrêtée à N, et qu'il y a peut-être d'autres lignes encore dans le fichier) ;
- la fonction principale reçoit ce nombre de lignes (disons n), puis rappelle la fonction de lecture sur le n+1è élément du tableau, en lui passant N-n comme limite (les erreurs "à un près" sont classiques dans ce genre de travail sur les tableaux, vérifie mes calculs sur le papier avant de coder (et puis c'est toujours un bon exercice)).
Les étapes 2 à 5 sont à faire en boucle, jusqu'à ce que tu ais lu tous tes fichiers. Je te passe les contrôles d'erreur habituels, c'est juste une idée d'algo que tu peux utiliser, à ajuster en fonction de tes besoins.