aide tableau de chaines et allocation dynamique !?

aide tableau de chaines et allocation dynamique !? - C - Programmation

Marsh Posté le 12-12-2008 à 14:52:32    

bonjour à tous !!!
 
je fais appel à vous car j'ai un programme à écrire, et je suis bien embêté. j'ai longuement cherché sur le net, mais je n'arrive pas à appliquer.
en effet, j'ai besoin de créer un tableau de chaines caractères. non pas avec un caractère par case, mais avec une chaine par case ( ou adresse ).
 
j'ai essayé un pointeur de tableau, ou un tableau à 2 dimensions, mais à chaque fois que je peux compiler quelque chose le programme plante.
 
auriez vous une petite idée pour m'aider ??
 
merci d'avance.


Message édité par electron-libre le 13-12-2008 à 19:26:43
Reply

Marsh Posté le 12-12-2008 à 14:52:32   

Reply

Marsh Posté le 12-12-2008 à 15:11:13    

Ben, tableau à 2 dimensions !
montab[nbLignes][longueur_max_des_chaines]


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 12-12-2008 à 15:30:57    

merci de ta réponse.
 
mais quand je fais ca, comment copier des caractères dedans ?
 
 

Code :
  1. montab[nbLignes][]='test';


 
quand je fais ça, impossible de compiler !

Reply

Marsh Posté le 12-12-2008 à 15:45:58    

en effet j'ai ce type d'erreur :
 
error: incompatible types in assignment of `char' to `char[1024][1024]'|

Reply

Marsh Posté le 12-12-2008 à 16:08:17    

char* tableau de chaine[nb_chaine]; et tu utilise malloc+strcpy pour remplir.

Reply

Marsh Posté le 12-12-2008 à 16:09:26    

L'instruction donne une erreur de syntaxe car une apostrophe a été utilisée au lieu d'un guillemet. Pour rappel, les apostrophes encadrent de simples caractères, alors que des guillemets encadrent des chaines de caractères.
De toutes manières l'instruction ainsi écrite montab[nbLignes][]="test"; ferait une assignation de l'adresse de la chaine "test", et non pas un déplacement de la chaine "test" dans le tableau. La solution consiste à utiliser strcpy : strcpy(montab[nbLignes], "test" );
 
Edit : Bien sûr, il faut avoir réservé de l'espace au préalable pour montab, soit avec un malloc(), soit avec une déclaration, sur le tas ou sur la pile, qui indique le nombre de lignes et de colonnes.


Message édité par olivthill le 12-12-2008 à 16:13:08
Reply

Marsh Posté le 12-12-2008 à 16:32:50    

oki je m'en vais tester tout ca .....merci !

Reply

Marsh Posté le 12-12-2008 à 16:41:14    

Ou plus simplement :
char montab[nbLignes][tailleChaines] = {"chaine1", "Chaine2"};
 


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 12-12-2008 à 17:03:32    

je suis vraiment dsl de faire mon gros boulet, mais je rame complètement.
comment attribuer l'espace avec malloc ou calloc pour un tableau deux dimensions de caractère.  
 
merci d'avance !

Reply

Marsh Posté le 12-12-2008 à 17:34:12    

Il vaudrait mieux que vous lisiez un cours ou même plusieurs cours sur le sujet parce que c'est un sujet important pour lequel les explications pourraient être assez longues.
 
En gros, il n'est peut-être pas nécessaire d'utiliser malloc() car si le tableau est petit ce serait prendre un marteau-pilon pour écraser une mouche. Il vaudrait mieux faire une déclaration ordinaire. Mais si c'est pour une formation, il est intéressant de se familiariser avec malloc().
 
Si vous voulez utiliser malloc(), alors il faut décider si vous voulez en faire un pour tout le tableau ou un malloc() pour chaque ligne du tableau. Là c'est un problème de conception. Les deux solutions sont possibles. Dans le premier cas, le tableau serait en fait considéré comme étant un tableau à une seule dimension, mais peut-être que votre professeur souhaiterait que vous ne biaisiez pas et que vous vous en teniez à un tableau à deux dimensions. Là cela dépend de ce que vous apprenez en cours.
 
Si vous voulez utiliser une déclaration normale, vous aurez à décider si vous faite une déclaration sur la pile ou sur le tas, et si c'est un tableau à deux dimensions stricto sensus, ou un tableau de pointeurs.


Message édité par olivthill le 12-12-2008 à 17:35:29
Reply

Marsh Posté le 12-12-2008 à 17:34:12   

Reply

Marsh Posté le 12-12-2008 à 18:04:20    

j'ai longuement essayé avec un simple tableau a deux dimension avec 1024 éléments dans chaque dimension, mais à chaque éxecution le programme plante, et je ne comprends pas d'où ca viens.
 
bref j'essaye d'aller au plus simple et au plus rapide, c'est vrais qu'il est dommage de ne pas apprendre à l'utiliser correctement, mais je n'ai pas trop le temps de m'y pencher!
 
en faite je doit créer un dictionnaire pour accueillir une table de codage afin de compresser un texte avec lempel ziv. en réalité plus le tableau est grand mieux c'est, mais en pratique ca parait difficile.

Reply

Marsh Posté le 12-12-2008 à 22:38:05    

Un exemple illustrera mieux je pense:
 

Code :
  1. #include <string.h>
  2. #include <stdio.h>
  3. int   main()
  4. {


 
Reprenons l'exemple du tableau a deux dimensions avec 1024 chaines de caracteres possible,
 

Code :
  1. char tab[1024][1024];


 
Tu peux maintenant copier une chaine dans un des elements du tableau en utilisant la fonction strcpy

Code :
  1. strcpy(tab[0], "chaine1" );
  2. strcpy(tab[1], "chaine2" );


 
Testons si le contenu des éléments du tableau sont bien remplit.

Code :
  1. printf("[%s] [%s]\n", tab[0], tab[1]);
  2. }


 
Résultat:

Code :
  1. [chaine1] [chaine2]


 

Reply

Marsh Posté le 13-12-2008 à 19:19:02    

oui merci beaucoup !  
j'ai bien avancé, mais j'ai maintenant un autre souci.......
 
en effet je dois établir un dictionnaire afin de compresser un texte.
ma méthode fonctionne bien pour de petit exemples (quelques centaines de caractères) mais sur de véritable textes mes tableaux explosent.
Je ne pense pas que je puisse résoudre le problème avec des malloc (peut etre que oui ??), et donc je ne sais pas comment créer un tableau qui s'agrandit en au fur et à mesure que je le rempli ....??
 
je ne comprends pas trop l'utilisation de malloc dans mon cas ?  
 
encore merci à vous !!

Message cité 1 fois
Message édité par electron-libre le 13-12-2008 à 19:30:17
Reply

Marsh Posté le 14-12-2008 à 10:45:23    

electron-libre a écrit :

oui merci beaucoup !  
j'ai bien avancé, mais j'ai maintenant un autre souci.......
 
en effet je dois établir un dictionnaire afin de compresser un texte.
ma méthode fonctionne bien pour de petit exemples (quelques centaines de caractères) mais sur de véritable textes mes tableaux explosent.
Je ne pense pas que je puisse résoudre le problème avec des malloc (peut etre que oui ??), et donc je ne sais pas comment créer un tableau qui s'agrandit en au fur et à mesure que je le rempli ....??
 
je ne comprends pas trop l'utilisation de malloc dans mon cas ?  
 
encore merci à vous !!


bah 1024x1024:
- c'est beaucoup pour la pile
- c'est 1024x1024 jusqu'à la fin des temps. C'est peut-être beaucoup trop ou jamais assez. c'est fixe quoi. Si par exemple tu te sers de ça pour stocker in fine une liste de prénoms (en général < 10 lettres), et bien tu gaches 99% de l'espace alloué.

Reply

Marsh Posté le 14-12-2008 à 14:16:15    

en fait, j'utilise l'algo lempel-ziv pour compresser un texte, mais les deux dimensions tu tableau (qui sert de dictionnaire" ) deviennent très vite énormes. résultat j'arrive seulement à coder des textes < à 1500 caractères. j'ai essayé de faire des allocations dynamique, je n'arrive pas à me servir de malloc avec un tableau 2D et puis apres il faudra de toute façon que je face une réallocation au fur et à mesure que le tableau grandi. mais je ne trouve pas de bon exemple sur le net .....

Reply

Marsh Posté le 14-12-2008 à 16:17:17    

malloc / realloc
 
à partir du moment où tu vas constituer un "dictionnaire", une liste de mots, ce n'est plus un tableau/matrice, ce n'est plus carré. Il te faut donc allouer N x char*, et ensuite faire N allocation ad-hoc en fonction de la taille du mot.
 
Ou passer sur un dictionnaire à taille fixe.

Reply

Marsh Posté le 14-12-2008 à 16:24:02    

Taz a écrit :


bah 1024x1024:
- c'est beaucoup pour la pile
- c'est 1024x1024 jusqu'à la fin des temps. C'est peut-être beaucoup trop ou jamais assez. c'est fixe quoi. Si par exemple tu te sers de ça pour stocker in fine une liste de prénoms (en général < 10 lettres), et bien tu gaches 99% de l'espace alloué.


On aurai pas le droit de faire :
 
string monTab[][1024];  
 
et après dans le code :
monTab = new string[nbLignesNecessaires][1024];


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 14-12-2008 à 16:26:01    

mouai, c'est bien ce que je pensais, mais je crains ne pas avoir le temps de mettre ça en place, je dois rendre mon travaille demain, et j'ai encore mon rapport à taper !
c'est d'autant plus  dommage que je suis vraiment tout près du but ....
 
merci pour tout, j'essaierai d'y revenir lorsque j'aurais un peut plus de temps, histoire de ne pas chuter pour la même raison la prochaine fois.
 
il y a il des langages ou la gestion mémoire soit plus aisée, voir automatique ?

Reply

Marsh Posté le 14-12-2008 à 16:28:48    

MEI a écrit :


On aurai pas le droit de faire :
 
string monTab[][1024];  
 
et après dans le code :
monTab = new string[nbLignesNecessaires][1024];


 
 
je ne pense pas que cela fonctionne.
 
et puis dans mon cas, lorsque je vais agrandir le nombre de ligne, la taille de la chaine va croitre elle aussi.

Message cité 1 fois
Message édité par electron-libre le 14-12-2008 à 16:29:25
Reply

Marsh Posté le 14-12-2008 à 16:28:55    

Oui les languages managé comme le Java/C# ou même les langages type Ruby/Python/PHP...
 
 


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 14-12-2008 à 16:29:51    

electron-libre a écrit :


 
 
je ne pense pas que cela fonctionne.
 
et puis dans mon cas, lorsque je vais agrandir le nombre de ligne, la taille de la va croitre elle aussi.


Si t'as besoin de changer la taille un tableau c'est pas forcement adapté => une liste c'est mieux (ou si C++ un vecteur...)
 
Après c'est sur parcourir une liste c'est chiant et parfois un probleme pour les perfs...
 
EDIT : Encore que doit y avoir des fonctions outils pour agrandir le tableau facilement sans perdre les données actuellement dedans...

Message cité 1 fois
Message édité par MEI le 14-12-2008 à 16:30:18

---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 14-12-2008 à 16:32:19    

MEI a écrit :

Oui les languages managé comme le Java/C# ou même les langages type Ruby/Python/PHP...
 
 


 :sweat:  :sweat:  :sweat:  :sweat:  :sweat:  :sweat:  
 
à part le C............, il faudrait que me mette à un nouveau langage.
que pensez vous de programmer ça avec matlab ? ou windev ? peut etre visual ?

Reply

Marsh Posté le 14-12-2008 à 16:37:05    

MEI a écrit :


Si t'as besoin de changer la taille un tableau c'est pas forcement adapté => une liste c'est mieux (ou si C++ un vecteur...)
 
Après c'est sur parcourir une liste c'est chiant et parfois un probleme pour les perfs...
 
EDIT : Encore que doit y avoir des fonctions outils pour agrandir le tableau facilement sans perdre les données actuellement dedans...


t'es gentil on parle de C.
 
malloc/realloc fait bien le boulot.
Y a aussi des bibliothèques pour gérer ça (par exemple glib).
 
Mais ici c'est clairement pour apprendre, donc c'est de l'abcédaire de pointeurs, se cogner la documentation de malloc/realloc et faire ses armes.
 
char** p;
 
voilà t'as le début ...

Reply

Marsh Posté le 14-12-2008 à 16:38:26    

electron-libre a écrit :


 :sweat:  :sweat:  :sweat:  :sweat:  :sweat:  :sweat:  
 
à part le C............, il faudrait que me mette à un nouveau langage.
que pensez vous de programmer ça avec matlab ? ou windev ? peut etre visual ?


Un jour j'ai voulu apprendre l'allemand, mais je savais pas faire comment faire une phrase sujet-verbe-complément, alors je me suis dit que je ferais mieux d'apprendre le finlandais.

Reply

Marsh Posté le 14-12-2008 à 16:40:13    

mais justement , en reallouent l'espace d'un tableau, ne va t on pas perdre ce qu'il y à dedans ??

Reply

Marsh Posté le 14-12-2008 à 16:42:10    

mais pourquoi ce casser la tete en C si il y a d'autre moyen d'y arriver plus facilement ? sachant qu'ici mon but n'est pas d'apprendre le C mais de compredre/créer un algo de compression.

Reply

Marsh Posté le 14-12-2008 à 16:43:26    

electron-libre a écrit :

mais justement , en reallouent l'espace d'un tableau, ne va t on pas perdre ce qu'il y à dedans ??


"Oui" mais en fait algorithmiquement on ferais :
- j'alloue mon tableau 2 de taille m
- je recopie mon tableau 1 de taille n dans mon tableau 2
- je desalloue mon tableau 1.
 
Je sais qu'en Delphi on a des methodes qui gère tout ça pour eviter de se taper les allocations de mémoire à la main. Je pense qu'en C y'a l'équivalent.
 
Mais effectivement si t'es en C, c'est direct du char** qu'il faut faire + lire la doc sur les pointeurs/tableaux + faire plein d'essai et voir in vivo le comportement.
Comme on dit c'est en forgeant qu'on deviens forgeron.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 14-12-2008 à 16:45:17    

mais man realloc bon sang.

Reply

Marsh Posté le 14-12-2008 à 16:45:52    

electron-libre a écrit :

mais pourquoi ce casser la tete en C si il y a d'autre moyen d'y arriver plus facilement ? sachant qu'ici mon but n'est pas d'apprendre le C mais de compredre/créer un algo de compression.


on perd notre temps en gros.

Reply

Marsh Posté le 14-12-2008 à 16:55:49    

non pas du tout ...... pourquoi dit tu ca ??
 
j'apprécie votre aide, et sans tout les tuto du net, je ne serai pas arrivé à grand chose. je pars du principe qu'il est toujours bon d'apprendre tout ce l'on peut apprendre, en l'occurrence une reallocation d'espace mémoire.
 
je dis juste qu'avec un autre langage la chose aurait peut être était plus aisée !  
mais dans tout les cas je vous remercie pour votre aide et vous garantie que vous ne perdez pas votre temps.

Reply

Marsh Posté le 14-12-2008 à 17:04:04    

Si t'es pressé par le temps, que ton but c'est faire de la compression/decompression par sur du Java/C# avec peut de chose qui te piegerons niveau gestion de la RAM et des grosses doc complete + framework enorme.
 
Par contre si tu connais rien sur la base algorythmique t'es quand meme mal barré. Mais clairement si le C ne t'es pas imposé et que tu connais rien aux pointeur/reference & tout ça, oui faut vite oublier le C maintenant ou bien aprendre les bases avant d'allé plus loin.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 14-12-2008 à 17:13:46    

belle philosophie : utiliser un marteu piqueur pr tuer une mouche ...
la feneantise n'a jamais servie personne. Alor sil fait comme tout le monde, il se sort les doigts, lis le k&R et ca suffira.

Reply

Marsh Posté le 14-12-2008 à 18:43:56    

je ne pense pas être une bête de c, mais je n'ai jamais eu de soucis avec le travaille que j'avais a faire et j'ai toujours eu d'honorable notes dans cette matière. c'est vraisemblablement la première fois que je bute sur un truc.(un truc qui n'est pas dans le cadre d'un cour de C mais de théorie de l'information).
 
bref tout ça pour dire que je connais les basses du C (des processeurs et des mémoire aussi avec des cours d'assembleur), et je pense que le C et le "code" a prendre pour débuter et comprendre les rouages de la programmation. après il n'est peut être pas nécessaire de réinventer la roue à chaque fois !?
 
quoi qu'il en sois j'aurais du mis prendre plus tot histoire de bien potasser ce "realloc" et ne pas l'utiliser comme un bourrin  !

Reply

Marsh Posté le 24-12-2008 à 12:47:55    

electron-libre: y a plein d'autres solutions possible, autant qu'il y a de collections différentes. Tu peux chainer des tableaux de taille fixe, par exemple, chaque tableau ayant un range d'indices. Tu rajoutes un accesseur dico->get(int indice) qui return tableauX[indice_decale].
 
Sinon AMHA la bonne facon de faire est d'abstraire ... quitte aprés à optimiser ta structure aprés derrière, eventuellement à reallouer des zones contigues de plus en plus grosse et en recopiant l'ancien contenu à chaque, si c'est optimal (à voir).
 


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
Reply

Marsh Posté le 24-12-2008 à 16:25:41    

philippe06 a écrit :

Sinon AMHA la bonne facon de faire est d'abstraire ... quitte aprés à optimiser ta structure aprés derrière, eventuellement à reallouer des zones contigues de plus en plus grosse et en recopiant l'ancien contenu à chaque, si c'est optimal (à voir).
 


Commande-toi un FM realloc pour Noël.

Reply

Marsh Posté le 24-12-2008 à 17:47:36    

Je dis pas que ça ne fonctionne pas, je dis que c'est du gaspillage de réallouer TOUT à chaque fois et qu'il n'est pas interdit de réfléchir un peu. Ce n'est pas pour rien si il y a plusieurs types de collections.


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
Reply

Marsh Posté le 24-12-2008 à 18:50:45    

electron-libre a écrit :

je ne pense pas être une bête de c, mais je n'ai jamais eu de soucis avec le travaille que j'avais a faire et j'ai toujours eu d'honorable notes dans cette matière. c'est vraisemblablement la première fois que je bute sur un truc.(un truc qui n'est pas dans le cadre d'un cour de C mais de théorie de l'information).
 
bref tout ça pour dire que je connais les basses du C (des processeurs et des mémoire aussi avec des cours d'assembleur), et je pense que le C et le "code" a prendre pour débuter et comprendre les rouages de la programmation. après il n'est peut être pas nécessaire de réinventer la roue à chaque fois !?
 
quoi qu'il en sois j'aurais du mis prendre plus tot histoire de bien potasser ce "realloc" et ne pas l'utiliser comme un bourrin  !


 
Je t'ai fait un truc vite fait:
 
Le .h
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define TRUE 1
  5. #define FALSE 0
  6. typedef struct SDictionary Dictionary;


 
Le .c
 

Code :
  1. #include"test.h"
  2. struct SDictionary
  3. {
  4. char** dictionary;
  5. int size;
  6. int index;
  7. };
  8. static char* initString(char const * const word)
  9. {
  10. char* returnWord = NULL;
  11. if(word != NULL)
  12. {
  13.  if((returnWord = malloc(sizeof(char) * (strlen(word)+1))) != NULL)
  14.  {
  15.   strcpy(returnWord, word);
  16.  }
  17. }
  18. return returnWord;
  19. }
  20. Dictionary* initDictionary(int size)
  21. {
  22. Dictionary* dictionary = NULL;
  23. if(size > 0)
  24. {
  25.  if((dictionary = malloc(sizeof(Dictionary))) != NULL)
  26.  {
  27.   if((dictionary->dictionary = malloc(sizeof(char*)*size)) != NULL)
  28.   {
  29.    dictionary->size = size;
  30.    dictionary->index = -1;
  31.   }
  32.   else {free(dictionary); dictionary = NULL;}
  33.  }
  34. }
  35. return dictionary;
  36. }
  37. void freeDictionary(Dictionary ** self)
  38. {
  39. int cpt = 0;
  40. if(self != NULL && *self != NULL)
  41. {
  42.  for(cpt = 0; cpt <= (*self)->index; cpt++)
  43.  {
  44.   printf("FOER \n" );
  45.   free((*self)->dictionary[cpt]);
  46.  }
  47.  free((*self)->dictionary);
  48.  free(*self);
  49.  *self = NULL;
  50. }
  51. }
  52. int putWord(Dictionary * const self, char const * const word)
  53. {
  54. int returnValue = TRUE;
  55. char* tmpWord;
  56. char** tmpDictionary = NULL;
  57. if(self != NULL && word != NULL)
  58. {
  59.  if((tmpWord = initString(word))!= NULL)
  60.  {
  61.   if(self->index < self->size - 1)
  62.   {
  63.    self->index++;
  64.    self->dictionary[self->index] = tmpWord;
  65.   }
  66.   else
  67.   {
  68.    if((tmpDictionary = realloc(self->dictionary, self->size * 2 * sizeof(char*))) != NULL)
  69.    {
  70.     self->dictionary = tmpDictionary;
  71.     self->size *= 2;
  72.     self->index++;
  73.     self->dictionary[self->index] = tmpWord;
  74.    }
  75.    else{free(tmpWord); returnValue = FALSE;}
  76.   }
  77.  }
  78.  else{returnValue = FALSE;}
  79. }
  80. return returnValue;
  81. }
  82. char* getWord(Dictionary const * const self, int index)
  83. {
  84. if(index <= self->index && self->index >= 0)
  85. {
  86.  return self->dictionary[index];
  87. }
  88. return NULL;
  89. }
  90. int main(void)
  91. {
  92. Dictionary * d = initDictionary(1);
  93. putWord(d, "eeeeeeeee" );
  94. putWord(d, "ssdfsf" );
  95. putWord(d, "ssssssssssssssssss" );
  96. printf("%s \n", getWord(d,0));
  97. printf("%s \n", getWord(d,1));
  98. printf("%s \n", getWord(d,2));
  99. freeDictionary(&d);
  100. return 0;
  101. }


Message édité par Anonymouse le 24-12-2008 à 20:13:30
Reply

Marsh Posté le 25-12-2008 à 23:05:45    

philippe06 a écrit :

Je dis pas que ça ne fonctionne pas, je dis que c'est du gaspillage de réallouer TOUT à chaque fois et qu'il n'est pas interdit de réfléchir un peu. Ce n'est pas pour rien si il y a plusieurs types de collections.


vecteur, liste chainée, toussa

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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