[C] Modifier chaine dans tableau à double entrée

Modifier chaine dans tableau à double entrée [C] - C - Programmation

Marsh Posté le 27-05-2008 à 21:07:57    

Bonjour,
C'est un problème de débutant je dois l'admettre :ange:  
J'ai eu beau cherché sur Google : rien (ou alors des trucs qui plante), donc je m'en remet à la communauté HFR qui m'a déjà aidé quelques fois :whistle:
 
Donc :
Dans mon main, j'ai un double tableau de chaines de caractères.
Je voudrais modifier une chaine (en connaissant les 2 coordonnées pour arriver à la bonne chaine) dans une fonction void, ça ne marche qu'a moitié, car quand je veux ensuite verifier dans mon main la "nouvelle" chaine, j'ai un truc bizarre (?°')
J'ai d'abord pensé à un erreur de cast dans ma fonction void, mais visiblement, c'est pas ça.  :sweat:  
 
Voici le code simplifié pour aller à l'essentiel ;)
 

Code :
  1. void point_addproperty(int x, int y, char *property, char *plan[20][20])
  2. {
  3. char buffer[26];
  4. strcpy(buffer,plan[x][y]);
  5. strcat(buffer,property);
  6. strcat(buffer,"|" );
  7. /*(1)*/ plan[8][4]=buffer;
  8. /*(2)*/ strcpy(plan[8][4],buffer);
  9. /*(3)*/ plan[8][4]=(char *)buffer;
  10. }
  11. void plan_init(char *plan[20][20])
  12. {
  13. int x,y;
  14. for (x=0; x<20; x++)
  15.  for (y=0; y<20; y++)
  16.    plan[x][y] = "";
  17. point_addproperty(8,5,"croix",plan);
  18. }
  19. int main(void)
  20. {
  21. char *plan[20][20];
  22. plan_init(plan);
  23. printf("Nouvelle valeur de la chaine 8.5 %s\n",plan[8][5]);
  24. }


 
La solution (1) me donne donc a mon main printf les ?°'
La solution (2) (que j'ai trouvé là : http://www.ltam.lu/tutoriel-ansi-c/prg-c86.htm ) me fait un beau plantage, ni + ni -
La solution (3) me donne pareil que (1)
 
J'ai essayé plusieurs solutions trouvé ci et là sur le net (dont les doubles pointeurs, cela dit j'y suis peutêtre pas bien arrivé), cela dit j'ai pas trouvé de cas identique au mien...
 
Ce qui est bizarre quand meme, c'est que :
- Si dans ma fonction add_property, je met "en dur" : plan[x][y] = "Hello";, là, ça marche tres bien dans mon main printf.
- Si dans ma fonction add_property, je fais un printf de plan[x][y] ou buffer, on voit bien aussi la bonne chaine...
 
Vraiment là, un petit coup de main serait le bienvenue ;)
 
Merci beaucoup :hello:


Message édité par ZePRiNCE le 27-05-2008 à 21:31:39

---------------
A VENDRE: Razer Chroma ARGB Controller / Boitier / Support Triple Screen / Ventirad / Carte USB3
Reply

Marsh Posté le 27-05-2008 à 21:07:57   

Reply

Marsh Posté le 27-05-2008 à 22:30:29    

Serait-ce tout bêtement parce que char *variable, n'est pas modifiable ?
 
J'ai lu le contraire sur un autre topic, que le coupable se dénonce :o
;)


---------------
A VENDRE: Razer Chroma ARGB Controller / Boitier / Support Triple Screen / Ventirad / Carte USB3
Reply

Marsh Posté le 27-05-2008 à 23:05:57    

Tu as un tableau plan de 20 X 20 pointeurs vers des chaînes de caractères.
Celà veut dire quoi exactement ? Que par exemple plan[0][0] contient l'adresse d'une chaîne de caractère.
Tu initialises ton tableau dans la fonction init.
Qu'as-tu fait ? Tu as mis dans chacune des cases l'adresse de la chaîne de caractères vide "" codée en dur dans la mémoire de l'ordinateur et vraisemblablement non modifiable. Cette chaîne de caractères est formée de un byte initialisée à 0.
 
Que font tes solutions 1 et 3.
Elles mettent dans les cases plan[x][y] l'adresse d'une chaîne de caractères valide seulement AU MOMENT DE L'ADRESSAGE, car buffer est une variable locale à la fonction, donc son adresse deviendra invalide après l'exécution de la fonction, c'est pourquoi tu obtiens des ?°', tu as de la "chance", ça pourrait être une plante complète.
 
Que fait la solution 2 : elle recopie à l'adresse indiquée en plan[8][4] la chaîne contenue dans buffer. Je te rappelle que la zone mémoire pointée par cette adresse contient une chaîne composée d'un seul caractère et cette zone sans doute non modifiable, il n'est pas étonnant que tu aies un plantage, la zone étant trop petite (1 byte) et sans doute non modifiable.
 
Pour faire ce que tu veux, il faut allouer une zone assez grande avec malloc (ne pas oublier le zéro terminal des chaînes) et y recopier buffer.
 

Reply

Marsh Posté le 27-05-2008 à 23:15:04    

Je pensais que faire plan[0][0]=""; mettait la chaine en question à "", visiblement je suis pas encore au point au niveau pointeur etc :/
 
En tout cas merci pour ces indications, ça semble déjà un peu + clair, je vais continuer dans cette voie :jap:
 
 
EDIT: en fait j'ai compris un peu mon erreur stupide.
Au début c'etait un tableau de 20x20 entiers, et je suis passé sur des char * sans trop réfléchir, alors qu'en fait, ça change tout  :ange:


Message édité par ZePRiNCE le 27-05-2008 à 23:17:58

---------------
A VENDRE: Razer Chroma ARGB Controller / Boitier / Support Triple Screen / Ventirad / Carte USB3
Reply

Marsh Posté le 27-05-2008 à 23:44:26    

Sans vouloir (volontairement) abuser des bonnes choses,

Trap D a écrit :

Pour faire ce que tu veux, il faut allouer une zone assez grande avec malloc (ne pas oublier le zéro terminal des chaînes) et y recopier buffer.


Pourrais-tu un peu détailler stp ?
 
On a pas encore vu malloc, mais à ce que j'ai compris, ça permet d'allouer dynamiquement de la mémoire, quand on sait pas "avant" de combien on a besoin (ce qui serait similaire a faire un char mot[n] avec n calculé ou demandé en scanf par exemple)
Moi, je sais qu'au maximum, mes chaines feront 26 caractere, caractere NULL compris.
 
J'ai encore simplifié le probleme

Code :
  1. void point_addproperty(int x, int y, char *property, char *plan[20][20])
  2. {
  3.   char str[80];
  4.   strcpy (str,plan[x][y]);
  5.   strcat (str,property);
  6. }
  7. int main(void)
  8. {
  9.   char *plan[20][20];
  10.   plan[8][5]="Hello";
  11.   point_addproperty(8,5," World",plan);
  12.   printf("On veut Hello World : %s\n",plan[8][5]);
  13. }


 
Meme si je faisais mon malloc, où penses-tu qu'il faille le faire ? au debut de la fonction add property  :??:  
 
Merci!  :jap:


Message édité par ZePRiNCE le 27-05-2008 à 23:44:51

---------------
A VENDRE: Razer Chroma ARGB Controller / Boitier / Support Triple Screen / Ventirad / Carte USB3
Reply

Marsh Posté le 28-05-2008 à 00:07:33    

pas bon tout ça.
Prend une fonctionnement simple:
- plan[x][y] est toujours alloué avec malloc
- ne suppose jamais de la taille de plan[x][y]
- pour changer la valeur de la chaine plan[x][y]:
   - realloc
   - crée une nouvelle chaine avec malloc, free l'ancienne
- dans tous les cas, fais du snprintf / strncpy / strncat en ayant lu la doc de ces fonctions (sans déconner)

Reply

Marsh Posté le 28-05-2008 à 00:46:14    

Code :
  1. char ***plan = (char ***) malloc(n * sizeof(char));
  2. for (x = 0; x < n; x++)
  3.  plan[x] = (char **) malloc(n * sizeof(char));
  4. for (x = 0; x < n; x++)
  5.  for (y = 0; y < n; y++)
  6.   plan[x][y]="A";


 
Ben c'est deja faux.
Bon ca me soule, je vais revenir à un tableau d'entier je crois, merci quand meme pour ton aide :/
 
J'essayerai de m'y repencher plus tard parce que c'est important et j'ai clairement des lacunes sur le sujet (pas tant que ça sur le cours de mon prof cela dit, mais bon, ne pas nous apprendre maloc :o)
Pour l'instant je dois finir quelque chose qui marche un peu pres, c'est un projet à rendre demain 9h  [:max evans]  
 
(S'il y a une âme charitable, je reste bien sûr preneur ;) )
 
Bonne fin de soirée tout le monde :bounce:


Message édité par ZePRiNCE le 28-05-2008 à 00:46:57

---------------
A VENDRE: Razer Chroma ARGB Controller / Boitier / Support Triple Screen / Ventirad / Carte USB3
Reply

Marsh Posté le 28-05-2008 à 08:32:20    

bah reste à X et Y connus à la compilation et fais ce que je t'ai dit.

Reply

Sujets relatifs:

Leave a Replay

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