Modification d'un caractère dans un tableau

Modification d'un caractère dans un tableau - C - Programmation

Marsh Posté le 16-08-2007 à 20:23:26    


Bonjour,
 
je suis en train de faire un programme pour un de mes cours et ca fait quelques heures maintenant que j'ai la même erreur sans pouvoir la résoudre...
 
j'obtiens une erreur de segmentation lorsque j'essaie d'assigner une valeur dans le tableau. (ligne 54)
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. /*
  6. *
  7. * Programme visant à générer toutes les possibilités
  8. * de mot de 8 caractères contenant des lettres majuscules
  9. * et/ou minuscules et/ou des chiffres.
  10. *
  11. */
  12. char *NextOne(char word[]);
  13. char AddOneChar(char tobemod);
  14. int main()
  15. {
  16. char * temp = "00000008";
  17. int i = 0;
  18. for(i=0;i<100;i++)
  19. {
  20. printf("temp = %s",temp);
  21. temp = (char *)NextOne(temp);
  22. }
  23. return 0;
  24. }
  25. /*
  26. *
  27. * Cette méthode renvoie la combinaison de mot de passe suivante.
  28. *  
  29. * @PRE  : word est un mot de 8 caractères  
  30. * @POST : word est la combinaison suivante du mot de 8 caractères.
  31. *         l'ordre est le suivant :
  32. *         00000000->00000001->...->0000000z->00000010->...
  33. *
  34. */
  35. char *NextOne(char word[])
  36. {
  37. char c;
  38. int i = 7;
  39. while(i!=-1)
  40. {
  41.  if (word[i]==122)
  42.  {
  43.   word[i] = '0';
  44.   i--;
  45.  }
  46.  else
  47.  {
  48.   word[i] = AddOneChar(word[i]); <---- l'erreur est ici
  49.   i=7;
  50.   break;
  51.  }
  52. }
  53. printf("%s\n",word);
  54. return word;
  55. }
  56. /*
  57. *
  58. * Cette méthode renvoie le caractère suivant dans cette
  59. * ordre : d'abord les chiffres de 0 à 9 puis les lettres
  60. * majuscules de A à Z puis enfin les lettres minuscules
  61. * de a à z.
  62. *
  63. * @PRE  : tobemod est un caractère de la série [a-zA-Z0-0./]
  64. * @POST : tobemod est le caractère suivant
  65. *
  66. */
  67. char AddOneChar(char tobemod)
  68. {
  69. switch (tobemod)
  70. {
  71.  case '9' : return 'A';
  72.  case 'Z' : return 'a'; 
  73.  default  : return tobemod+1;
  74. }
  75. }


 
Je rame à mort, j'espere que quelqu'un d'entre vous pourra m'aider.
 
Merci d'avance pour toute aide!  :)

Reply

Marsh Posté le 16-08-2007 à 20:23:26   

Reply

Marsh Posté le 16-08-2007 à 20:35:01    

Mouais, classique. Tu modifies une chaine statique. Les compilos marque la zone occupée par ces chaines en read only. En général, ils en profitent pour optimiser en réutilisant les chaines similaires. Du coup si tu modifiais une chaine, ça pourrait avoir des répercutions dans d'autre partie du code : l'horreur totale.
 
Il suffit de changer ta ligne 20 en :
 

Code :
  1. char temp[] = "00000008";


 
Edit: rhôôooo, le serveur avait mis plein de fotes de grammaires, orthos, typos, ... dans mon post !!


Message édité par tpierron le 16-08-2007 à 20:38:11
Reply

Marsh Posté le 16-08-2007 à 20:51:46    

Merci de m'avoir répondu aussi vite,
 
c'est clair que c'est le genre d'erreur classique en c, c'est pas encore trop la joie avec les pointeurs...
 
mais bon, maintenant il ne compile plus...
 
il me dit : c:25: error: incompatible types in assignment
 
j'ai enlever le (char *) mais rien n'y fait...je suis perdu!  :cry:

Reply

Marsh Posté le 16-08-2007 à 21:37:40    

c'est bon, ca marche plus ou moins
 
j'ai changé la ligne 25 par  
*temp = NextOne(temp);
 
maintenant ça compile et ca marche,
 
mais le problème c'est que j'ai besoin d'appeller la methode NextOne() avec un char * comme arguments et pas un char [] et il me fait à nouveau l'erreur de segmentation... :pfff:

Reply

Marsh Posté le 16-08-2007 à 22:06:46    

je ne comprends pas pourquoi ton NextOne retourne quelque chose.
Surtout que ce que tu retournes c'est l'adresse du tableau que tu lui passes en paramètre.
Si tu le déclares en

Code :
  1. void NextOne(char word[])

et que tu retournes rien ça doit bien suffire  

Reply

Marsh Posté le 16-08-2007 à 22:31:01    


 
segmentation fault à nouveau...
 
J'aime beaucoup le c, mais la ya vraiment des jours... incapable de changer un caractère dans un tableau ,c'est quand même la gène...
 
 
en tout cas merci pour ta réponse SquiZZ.
 
J'ai modifié ma methode en void, mais ca ne change rien,
 
char * temp = ... pose tjrs des problèmes.
 
Quelqu'n aurait une solution?

Reply

Marsh Posté le 16-08-2007 à 22:37:48    

uh, t'as fait ce qu'a dit tpierron ?

Reply

Marsh Posté le 16-08-2007 à 23:43:08    


 
Oui j'ai fait ce qu'il a dit(et ca a marché),  
mais le problème c'est que le bout de code que j'ai montré fait parti d'un programme 10fois plus gros,
ca marchait bien au début mais maintenant j'ai cette erreur de segmentation, j'ai pas fait de sauvegarde assez souvent (shame on me)
et je me retrouve bloqué, si je commence à changer la variable à passer en argument ,je devrais changer tout le programme...
 
donc je me retrouve toujours avec le même problème de base:
 
- Comment modifier un élement d'un string définit par : char * temp = "TotoLeHeros"?
 
j'en deviens dingue  :pt1cable:

Reply

Marsh Posté le 17-08-2007 à 02:00:38    

smurf4xp a écrit :


- Comment modifier un élement d'un string définit par : char * temp = "TotoLeHeros"?


 
on ne peut pas
"TotoLeHeros" est une chaine constante
 
en faisant ça, tu ne fait que dire : "le pointeur temp pointe sur la chaine constante (donc immuable) "TotoLeHeros"", ce qui ne te permet pas de modifier la chaine puisqu'elle est constante
 
par contre tu peux faire :

Code :
  1. char *temp = strdup ("TotoLeHeros" );


 
mais une fois que tu en auras plus besoin il ne faudrat pas que tu oublie de faire

Code :
  1. free(temp);


 
sinon tu fais simplement

Code :
  1. char temp[] = "TotoLeHeros";


la tu peux la modifier, mais ça t'oblige à changer tout ton programme [:spamafote]


Message édité par Deadog le 17-08-2007 à 02:04:03
Reply

Marsh Posté le 17-08-2007 à 12:00:15    

merci pour ta réponse deadog!
 
tu as raison en declarant comme ceci  

Code :
  1. char *temp = "TotoLeHeros" ;


je ne peux plus changer le string... (est cela qu'on appelle une lvalue?)
 
J'ai finalement pu résoudre mon problème hier (ou ce matin  :sweat: ?)
 
pour cela j'ai fait comme suit:  

Code :
  1. char * temp = malloc(sizeof(char)*9)
  2. strncpy(temp,"totoleheros",8);


 
ce qui resolvait mon problème, mais je vais retenir ta solution (je ne connaissais pas strdup).
 
Je remercie tout ceux qui m'ont aidé, c'est franchement sympa ce que vous faites.
 
Continuez comme ca ! :hello:  :jap:

Reply

Marsh Posté le 17-08-2007 à 12:00:15   

Reply

Marsh Posté le 17-08-2007 à 13:33:03    

hum, strdup te fait le malloc + le strcpy ;)

 

ce qui n'est pas plus mal parce que dans ce que tu as fais tu prend un gros risque : tu paris sur le faite que le bout de mémoire alloué par malloc contient initiallement que des 0, ce qui n'est pas toujours le cas.

 

malloc tu donne un bout de mémoire sans la remettre à zero, donc tu peux très bien obtenir ce qu'il y avant, c'est à dire tout et n'importe quoi, et en particulier pas forcément des 0
ton strncpy s'arrête à 8 et ne met donc pas le 0 final

 

tiré de la page man de strncpy :

Citation :

La fonction strncpy() est identique, sauf que seuls les n premiers octets de src sont copiés. Ainsi, s’il n’y a pas de caractère nul dans les  n  premiers octets de src, la chaîne résultante ne disposera pas de caractère nul final.

 

Chez toi ça a marché uniquement parce que tu as eu la chance que malloc te retourne un bout de mémoire avec que des 0.
Pour éviter ça tu peux utiliser strdup dans ce cas particulier, et plus générallement tu peux utiliser calloc :

 
Code :
  1. char * temp = calloc(9, sizeof(char));
  2. strncpy(temp,"totoleheros",8);
 

calloc t'alloue une zone mémoire et te la met à zéro ;)

 

une autre méthode et de faire ça à chaque fois que tu utilise strncpy :

Code :
  1. char * temp = malloc(sizeof(char)*9);
  2. strncpy(temp,"totoleheros",8);
  3. temp[8] = 0;


Message édité par Deadog le 17-08-2007 à 13:35:29
Reply

Marsh Posté le 17-08-2007 à 13:57:43    

smurf4xp a écrit :


je suis en train de faire un programme pour un de mes cours et ca fait quelques heures maintenant que j'ai la même erreur sans pouvoir la résoudre...

 

j'obtiens une erreur de segmentation lorsque j'essaie d'assigner une valeur dans le tableau. (ligne 54)

 



Il suffit d'utiliser une chaine modifiable :

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. /*
  6. *
  7. * Programme visant à générer toutes les possibilités
  8. * de mot de 8 caractères contenant des lettres majuscules
  9. * et/ou minuscules et/ou des chiffres.
  10. *
  11. */
  12. /*
  13. *
  14. * Cette méthode renvoie le caractère suivant dans cette
  15. * ordre : d'abord les chiffres de 0 à 9 puis les lettres
  16. * majuscules de A à Z puis enfin les lettres minuscules
  17. * de a à z.
  18. *
  19. * @PRE  : tobemod est un caractère de la série [a-zA-Z0-0./]
  20. * @POST : tobemod est le caractère suivant
  21. *
  22. */
  23. char AddOneChar (char tobemod)
  24. {
  25.    switch (tobemod)
  26.    {
  27.    case '9':
  28.       return 'A';
  29.    case 'Z':
  30.       return 'a';
  31.    default:
  32.       return tobemod + 1;
  33.    }
  34. }
  35. /*
  36. *
  37. * Cette méthode renvoie la combinaison de mot de passe suivante.
  38. *
  39. * @PRE  : word est un mot de 8 caractères
  40. * @POST : word est la combinaison suivante du mot de 8 caractères.
  41. *         l'ordre est le suivant :
  42. *         00000000->00000001->...->0000000z->00000010->...
  43. *
  44. */
  45. char *NextOne (char word[])
  46. {
  47.    int i = 7;
  48.    while (i != -1)
  49.    {
  50.       if (word[i] == 122)
  51.       {
  52.          word[i] = '0';
  53.          i--;
  54.       }
  55.       else
  56.       {
  57.          word[i] = AddOneChar (word[i]);
  58.          i = 7;
  59.          break;
  60.       }
  61.    }
  62.    printf ("%s\n", word);
  63.    return word;
  64. }
  65. int main (void)
  66. {
  67.    char temp[] = "00000008";
  68.    int i = 0;
  69.    for (i = 0; i < 100; i++)
  70.    {
  71.       printf ("temp = %s", temp);
  72.       NextOne (temp);
  73.    }
  74.    return 0;
  75. }


Message édité par Emmanuel Delahaye le 17-08-2007 à 14:00:13

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

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