Problème de allocation de tableau

boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 - 22 août 2009 à 20:17
uaip Messages postés 1466 Date d'inscription mardi 20 février 2007 Statut Membre Dernière intervention 7 février 2011 - 23 août 2009 à 20:45
Bonsoir,

Je voulais copier le contenu de fichier "exemple.txt" dans un tableau
dynamique t de taille inconnue en avance. J'utilise le tableau pour
faciliter la manipulation après.
Chaque ligne de fichier contient une chaine de caractère :
nom
prenom
age
adresse
emploi

Voici le programme:
Code :

int allocation(int N)
{
FILE *fp;
char *t,s[100],attribut[32];
int i;

t = (char *) malloc((N)*sizeof(char));
fp=fopen("exemple.txt","r");

for(i=0; i < N;i++)
{
fgets(s, 100, fp);
sscanf(s,"%s",attribut);
strcpy(t[i],attribut);
printf("%s ",t[i]);
}

fclose(fp);
return 0;
}

int main ()
{
FILE *fp;
char s[100];
int N=0;
while (fgets(s,100,fp))!=NULL)
N++;
allocation(N);
fclose(fp);
return 0;

}

J'ai remarqué que le problème déclenche juste après l'ouverture de
fichier "exemple.txt" dans la fonction allocation(N).
Comment on résoudre ce problème ?

Je serais très reconnaissant pour vos aides.

Merci.

8 réponses

boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
22 août 2009 à 20:18
Voici le programme:

int allocation(int N)
{
FILE *fp;
char *t,s[100],attribut[32];
int i;

t = (char *) malloc((N)*sizeof(char));
fp=fopen("exemple.txt","r");

for(i=0; i < N;i++)
{
fgets(s, 100, fp);
sscanf(s,"%s",attribut);
strcpy(t[i],attribut);
printf("%s ",t[i]);
}

fclose(fp);
return 0;
}

int main ()
{
FILE *fp;
char s[100];
int N=0;
while (fgets(s,100,fp))!=NULL)
N++;
allocation(N);
fclose(fp);
return 0;

} 
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
22 août 2009 à 21:14
Ton tableau t est un tableau de N pointeurs... qui ne pointent sur rien. Faut allouer de la mémoire pour stocker les chaînes.

tu peux remplacer par exemple par :

t = (char *) malloc(32*(N)*sizeof(char));
...
strcpy(t+32*i,attribut);
printf("%s ",t+32*i);
0
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
22 août 2009 à 23:58
Bonsoir,

Oui çà marche.
Mais, je ne sais pas pourquoi vous mettez 32 ?

Moi, j'ai mis en déclaration attribut[32] au hasard car je ne sais pas la taille de l'attribut. Donc, la taille de l'attribut peut dépasser 32 ou ne pas dépasser 32.

Merci.
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
23 août 2009 à 13:24
c'était parce que vous aviez mis 32...
Effectivement, cette taille doit suffir à contenir tous les attributs; s'il y en a un de longueur supérieure ça va évidemment planter; il faut choisir une taille suffisante pour être sûr que ça ira.
Si vraiment il n'y a pas de limite à la taille de l'attribut, faudra changer de méthode et allouer chaque chaîne dynamiquement après avoir récupéré la taille de l'attribut correspondant.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
23 août 2009 à 14:15
Bonjour,
Votre solution marche.
Il y a une autre solution pour la fonction "allocation (N)" :
int allocation(int N)
{
   FILE *fp;
   char **t,s[100],attribut[32];
   int i,j;
 
   t = malloc(N * sizeof(*t));
   if(t== NULL)
   {
      printf("probleme d'allocation\n");
      exit(0);
   }
 
   fp=fopen("exemple.txt","r");
   if (fp == NULL)
   {
      printf("impossible d'ouvrier le fichier\n");
      exit(0);
   }
 
   rewind(fp);
   //copier le contenu du fichier dans le tableau
   for(i=0; i < N;i++)
   {
      fgets(s, 100, fp);
      sscanf(s,"%s",attribut);
      t[i] = malloc(strlen(attribut)+1);
      strcpy(t[i],attribut);
      printf("%s\n",t[i]);
   }
 
   //affichage le contenu de tableau
   for(j=0;j<N;j++)
      printf("j=%d %s\n",j,t[j]);
   fclose(fp);
   return 0;
}


Cette solution consiste à créer un pointeur de pointeur sur char (char **t), d'allouer ensuite la place nécessaire pour stocker l'adresse des chaînes de caractères puis, pour chaque ligne lue, d'allouer la taille nécessaire pour contenir la chaîne et de copier cette chaîne.

- Que pensez-vous ?
- Laquelle de deux solutions est moins gourmande en mémoire et le moins en temps d'exécution ?

Merci.
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
23 août 2009 à 19:05
Très bien comme ça aussi.
Au niveau performances, la deuxième est (largement) moins rapide puisqu'il faut allouer la mémoire pour chaque chaîne.
Après, niveau mémoire, ça dépend du contenu du fichier; si tous les attributs ont plus ou moins la même taille ça sera pareil, si par contre y en a des beaucoup plus longs que d'autres la première solution sera plus gourmande en mémoire puisqu'il faudra que toutes les chaînes aient la longueur max. Après, bon, à part si le fichier est immense, la différence sera négigeable.
0
boualiasma Messages postés 393 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 23 décembre 2011 5
23 août 2009 à 19:19
Bonjour,

Je vous remercie pour votre aide. J'ai un petit problème d'ouverture d'un fichier.
J'ai remarqué que à chaque fois on appelle une fonction dans une partie du mon programme, il y a une ligne s'ajoute à la fin. ceci c'est bon et à la fin du programme j'obtiens le fichier "resultat.txt" qui contient le résultat souhaité.
Ceci grâce au mode de l'ouverture de fichier :
fpR = fopen ("resultat.txt","a");


Mais, lorsque je exécute le programme une autre fois, je remarque que le contenu de l'ancienne exécution reste.

Je voudrais à chaque exécution j'obtiens le contenu réel du fichier "resultat.txt" et donc pas du cumul

il y a un autre mode qui permet d'ajouter à la fin du fichier et ouvrir un nouveau fichier dans la prochaine exécution ?

Que proposez-vous ?
0
uaip Messages postés 1466 Date d'inscription mardi 20 février 2007 Statut Membre Dernière intervention 7 février 2011
23 août 2009 à 20:45
Salut,
Euh... j'ai pas tout compris. J'ai pas tout lu, donc je risque d'être hors-sujet, mais quelle idée de vouloir récupérer le contenu dans une chaine par paliers ?
Il y a des fonctions toutes prêtes pour récupérer le contenu d'un fichier dans une chaine. Moi je ferais comme ça:

char *donnees=NULL;
void allocation() {
    FILE *fichier=fopen("fichier","r");//Ouverture du fichier
    if (fichier == NULL) return;//Vérification d'ouverture
    fseek(fichier,0,SEEK_END);//Indicateur de position du fichier à la fin
    int taille=ftell(fichier);//Nombre d'octets de 0 à l'indicateur (= taille du fichier)
    rewind(fichier);//Indicateur de position du fichier au début
    donnees=(char*)malloc(taille);//Tableau de même taille que le fichier
    if (donnees == NULL) return; //Vérification d'allocation
    int res=fread(donnees,1,taille,fichier);//Copie du contenu vers le tableau
    if (res != taille) return;//Vérification de copie
    fclose(fichier);//Fermeture du fichier
}
int main() {
    allocation();
    return 0;
}


Vire la var globale si tu veux.
Dites moi si je suis hors-sujet, sinon cette solution vaut largement les votres.

Cordialement, uaip.
0
Rejoignez-nous