Tableau de chaînes de caractères...

Tableau de chaînes de caractères... - C++ - Programmation

Marsh Posté le 18-03-2003 à 11:34:22    

Bonjour,
 
j'ai un problème lorsque je veux passer à un module un tableau de chaînes de caractères pour qu'il le remplisse.
 
ce module est censé lire toutes les lignes d'un fichier index.txt et les placer dans le tableau correspondant s'appelant indexv.
 
le remplissage dans le module se passe bien (je peux lire le tableau depuis le module sans pb) mais quand on revient dans le main, je n'arrive plus à y accéder. Voici le code :
 
 
[g]main.c[/b]

Code :
  1. #include<string.h>
  2. #include "texindex.h"
  3. int main(int argc, char** argv)
  4. {
  5.   int i=0;
  6.   int indexc=0;
  7.   char** indexv;
  8.   //lecture du fichier d'index de mots :
  9.   readIndexTxt(argv[1],&indexc,&indexv);
  10.  
  11.   printf("\nVérification : %d\n",indexc);
  12.   for(i=0;i<indexc;i++)
  13.     {
  14.       printf("Vérification : indexv[%d]\t:\t%s\n",i,indexv[i]);
  15.     }
  16.   printf("\n" );
  17.   return EXIT_SUCCESS;
  18. }


 
texindex.c

Code :
  1. #include "texindex.h"
  2. void readIndexTxt(char* filename, int* indexc, char*** indexv)
  3. {
  4.   int i=0;
  5.   FILE* f;
  6.   //tampon de lecture
  7.   char s[40];
  8.  
  9.   if((f=fopen(filename,"r" ))==NULL)
  10.     {
  11.       printf("Erreur d'ouverture du fichier %s\n",filename);
  12.       exit(1);
  13.     }
  14.   //comptage des mots contenus dans le fichiers (un par ligne)
  15.   (*indexc)=0;
  16.   while((fgets(s,80,f))!=NULL) (*indexc)++; //ajout d'un mot
  17.   //allocation mémoire
  18.   (*indexv)=malloc((*indexc)*sizeof(char[40]));
  19.   //retour au début du fichier
  20.   rewind(f);
  21.   //remplissage de la liste de mots
  22.   printf("Chargement de la liste de mots" );
  23.   printf("\n" );
  24.   while((fgets(s,80,f))!=NULL)
  25.     {
  26.       (*indexv)[i]=s;
  27.       printf("Chargement de : indexv[%d]\t:\t%s",i,(*indexv)[i]);
  28.       i++;
  29.     }
  30.   fclose(f);
  31. }


 
texindex.h

Code :
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. void readIndexTxt(char* filename, int* indexc, char*** indexv);


 
makefile

Code :
  1. all : main clean
  2. main : main.o texindex.o
  3. gcc -g main.o texindex.o -o main
  4. main.o : main.c texindex.h
  5. gcc -g -c main.c
  6. texindex.o : texindex.c texindex.h
  7. gcc -g -c texindex.c
  8. clean : main
  9. rm *.o


 
Et voici le résultat :

Code :
  1. Chargement de la liste de mots
  2. Chargement de : indexv[0]       :       tex
  3. Chargement de : indexv[1]       :       latex
  4. Chargement de : indexv[2]       :       miktex
  5. Chargement de : indexv[3]       :       jadetex
  6. Chargement de : indexv[4]       :       pstricks
  7. Vérification : 5
  8. Vérification : indexv[0]        :       pstr  q@¼
  9. Vérification : indexv[1]        :       pstr  q@¼
  10. Vérification : indexv[2]        :       pstr  q@¼
  11. Vérification : indexv[3]        :       pstr  q@¼
  12. Vérification : indexv[4]        :       pstr  q@¼


 
Une idée  :??:  :??: ??
 
Merci !

Reply

Marsh Posté le 18-03-2003 à 11:34:22   

Reply

Marsh Posté le 18-03-2003 à 11:36:55    

(*indexv)[i]=s;
 
tu copies le pointeur vers une chaine stockée dans une variable locale :o
 
strcpy((*indexv)[i], s);
me semble plus indiqué


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 18-03-2003 à 14:10:39    

oulala ! t'as fais deux bêtises, je t'explique dès que j'ai le temps ;)

Reply

Marsh Posté le 18-03-2003 à 14:10:46    

commence par simplifier:
 
void readIndexTxt(char* filename, int* indexc, char** indexv)  
 
et
//lecture du fichier d'index de mots :  
 readIndexTxt(argv[1],&indexc,indexv);

Reply

Marsh Posté le 18-03-2003 à 14:14:21    

sizeof(char[40])
 
beurk
 
sizeof ma_variable
sizeof(mon_type)

Reply

Marsh Posté le 18-03-2003 à 14:15:47    

la première, c'est un détail, mais dangeureux quand même,
tu déclares

Code :
  1. char s[40];

donc tu réserves 40 caractères et tu autorises fgets à y écrire 80 caractères,

Code :
  1. fgets(s,80,f)

, mets une chaine de plus de 40 caractères sur une ligne dans ton fichier et ton pc va être content, surtout si l'impact n'est pas tout de suite visible.

Reply

Marsh Posté le 18-03-2003 à 14:20:45    

y au aussi autre problèem. il faut faire l'allocation en 2 fois
 
une boucle pour allouer n pointeurs de caractères
une autre pour allouer m caracteres pour chacune de ces n pointeurs.
 
si tu fais les 2 d'un coup, il faut proprement tu n'as qu'un char* et pas un char* donc la double indirection ne fonctionne pas

Reply

Marsh Posté le 18-03-2003 à 14:22:35    

deuxième erreur :
 
tu utilises indexv comme un tableau de pointeur sur des chaines

Code :
  1. printf("Vérification : indexv[%d]\t:\t%s\n",i,indexv[i]);


hors tu réserve je ne sais pas trop koi en mémoire, un truc à cheval entre les deux mallocs nécessaire

Code :
  1. (*indexv)=malloc((*indexc)*sizeof(char[40]));


oui, deux mallocs sont nécessaire,
un pour le tableau de pointeurs
le deuxième dans une boucle pour allouer l'espace pour chaque chaine ; idéalement, tu peux allouer juste l'espace nécessaire pour la longueur de chaque chaine, ou prévoir plus (40 par exemple) si tu as l'intention de les modifier, de les rallonger ...
bref je te laisse corriger ton code

Reply

Marsh Posté le 18-03-2003 à 14:26:05    

bien entendu il existe la possibilité d'alloué tout l'espace nécessaire à indexv puis de l'indexer par paquets de 40 caractères, seulement il faut soit changer sa déclaration, soit changer la manière d'y acceder
sur ce, @+, je repasserais dès que j'ai un peu de temps voir si tu t'en sors  :wahoo:

Reply

Marsh Posté le 18-03-2003 à 14:37:51    

dernier détail, bien que ton compilateur ajoute le code nécessaire à ton application pour que losrque celle-ci se termine, toutes les ressources allouées soient libérées, il est préférable de libérer chaque allocation de mémoire avec la fonction free() dès que tu as fini d'utiliser ta super liste de mots en tex  :lol:  surtout si ton programme fais autre chose après et qu'il n'en a plus besoin.

Reply

Marsh Posté le 18-03-2003 à 14:37:51   

Reply

Marsh Posté le 20-03-2003 à 16:55:31    

voilà j'ai trouvé comment faire un tableau dynamiques de chaines de caractères de longuer statique :
 

Code :
  1. char (*x)[20];
  2. int nombreDeChaines;
  3. nombreDeChaines = 4;
  4. x = (char (*)[20])malloc(sizeof(char[25])*nombreDeChaines);
  5. strcpy(x[0],"salut" );
  6. strcpy(x[1],"allo" );
  7. printf("%s\n%s\n",x[0],x[1]);
  8. // ...
  9. free(x);


 
Maintenant, jen'arrive pas à passer le tableau x en argument à ma fonction readIndexTxt dans laquelle je voudrais faire la partie allocation et remplissage du code précédent
 
Pouvez-vous m'éclairer ??
 
Merci  :)

Reply

Marsh Posté le 20-03-2003 à 19:29:34    

cf mon post plus haut

Reply

Marsh Posté le 20-03-2003 à 20:10:21    

Deaddy a écrit :

cf mon post plus haut


si il alloue la mem dans sa fct, il est obligé de faire un char *** ... sinon, il ne pourra pas modifier le pointeur passé en param !

Reply

Marsh Posté le 20-03-2003 à 22:12:53    

exact ! mais dans ce cas (le tablo n'a pas été alloué) ca sert à rien de le passer en param
 
autant faire un truc du style:
char** readIndexTxt(char* filename, int* indexc)
{
char **x;
...
allocation de x
...
pas de free(x);
return x;
}

Reply

Marsh Posté le 21-03-2003 à 06:59:05    

ceyquem a écrit :

Code :
  1. char (*x)[20];
  2. int nombreDeChaines;
  3. nombreDeChaines = 4;
  4. x = (char (*)[20])malloc(sizeof(char[25])*nombreDeChaines);
  5. ...


Allocation de [25] mais cast en [20], ça va pas marcher...
C'est pas interdit de simplifier:

Code :
  1. typedef char Chaine[20];
  2. int nombreDeChaines = 4;
  3. Chaine* x= (Chaine *)malloc(sizeof(Chaine)*nombreDeChaines);


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 21-03-2003 à 14:08:15    

j'ai résolu mon pb en utilisant :
 

Code :
  1. typedef char str40[40+1];


 
et en faisant
 

Code :
  1. strcpy((*indexv)[i],s);


 
merci à tous pour votre aide !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed