Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1345 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Langage C : concaténation de chaines de caractères

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Langage C : concaténation de chaines de caractères

n°1981935
rahela
Posté le 08-04-2010 à 12:17:15  profilanswer
 

Bonjour,  
 
j'essaie d'écrire une méthode qui prend en argument une chaine de caractères correspondant au nom d'un fichier : par exemple "mon_fichier" et qui par la suite lui associe le dossier dans lequel il se situe ainsi que son extension.  
 
Voici mon tout petit bout de code :  
 
 

Code :
  1. void ma_fonction(char *mon_fichier )
  2. {
  3. // chaines à concatener avec mon_fichier
  4. char *chemin = "files\\";
  5. char *extension = ".jpg";
  6. //j'affiche chacune de ces chaines pour vérifier
  7. printf("%s\n",chemin);
  8. printf("%s\n",nom_fichier);
  9. printf("%s\n",extension);
  10.        
  11. //je concatene le chemin avec mon_fichier
  12. strcat(chemin,nom_fichier);
  13. //j'affiche pour vérifier la concatenation
  14. printf("%s\n",chemin);
  15. //je reconcatene ensuite avec l'extension
  16. strcat(chemin,extension);
  17. printf("%s\n",chemin);
  18. }
  19. int main(void){
  20.         enregistrer_image("mon_fichier" );
  21.         return 0;
  22. }


 
 
A la fin de la méthode, chemin devrait correspondre à la chaine "files\mon_fichier.jpg", mais cela ne marche pas lorsque je concatène chemin avec la chaine passée en paramètres (ligne 12)... cela marche seulement avec les chaines que j'ai créées à l'intérieur de ma fonction. Voilà si quelqu'un pouvait m'expliquer... je ne vois pas pourquoi cela ne fonctionne pas...
Merci pour votre aide,
 
bonne journée.

mood
Publicité
Posté le 08-04-2010 à 12:17:15  profilanswer
 

n°1981937
Turkleton
I don't quite understand you
Posté le 08-04-2010 à 12:25:22  profilanswer
 

rahela a écrit :

je ne vois pas pourquoi cela ne fonctionne pas...


Peut-être parce que "nom_fichier" != "mon_fichier" ?
 
De rien :D


Message édité par Turkleton le 08-04-2010 à 12:25:42

---------------
If you think it could look good, then I guess it should
n°1981940
rahela
Posté le 08-04-2010 à 12:35:32  profilanswer
 

ahah non c'est une erreur , j'ai voulu bidouiller dans mon message...
Dans mon code les noms correspondent bien, et j'ai bien une erreur (du type segmentation fault (core dumped))
Je remets le VRAI code   :ange:  
 

Code :
  1. void ma_fonction(char *nom_fichier )
  2. {
  3. char *chemin = "files\\";
  4. char *extension = ".jpg";
  5. printf("%s\n",chemin);
  6. printf("%s\n",nom_fichier);
  7. printf("%s\n",extension);
  8. strcat(chemin,nom_fichier);
  9. printf("%s\n",chemin);
  10. strcat(chemin,extension);
  11. printf("%s\n",chemin);
  12. }
  13. int main(void){
  14. ma_fonction("nom_fichier" );
  15. return 0;
  16. }


 
mercii

n°1981942
Turkleton
I don't quite understand you
Posté le 08-04-2010 à 12:57:55  profilanswer
 

Tu as bien inclus "#include <string.h>" hein ?
 
Et tu fais bien de préciser que ça plante à l'exécution, et pas à la compilation.
Du coup, je pense à un débordement en mémoire où il ne doit pas y avoir assez de place de réservée pour agrandir ta variable "chemin".
 
Essaie de la déclarer avec  

Code :
  1. char[100] chemin;



---------------
If you think it could look good, then I guess it should
n°1982015
tpierron
Posté le 08-04-2010 à 14:50:34  profilanswer
 

Ouais, aucune chance que ton code fonctionne.
 
Tu déclares un pointeur sur une chaine de caractère (char * chemin) et tu lui assignes une chaine statique: non seulement il n'y a pas la place à la fin de la chaine pour rajouter quoi ce soit, mais en plus ces chaines sont en lectures seules, toute tentative d'écriture = plantage direct.
 
Pour contourner le problème tu peux faire comme Turkleton t'as dit : déclarer une tableau et l'initialiser dans la foulée :
 
char chemin[100] = "files\\";
 

n°1982018
olivthill
Posté le 08-04-2010 à 14:54:45  profilanswer
 

En effet

char *chemin = "files\\";

ne réserve de la place que pour f-i-l-e-s-\-0, soit sept caractères.
Mais

strcat(chemin,nom_fichier);

metstous les caractères de nom_fichier dérrière, et cela déborde donc.
La solution est de réserver plus d'espace, par exemple :

Code :
  1. char *chemin = "files\\";
  2. char *extension = ".jpg";
  3. char full_name[250];
  4. strcpy(full_name, chemin);
  5. strcat(full_name, nom_fichier);
  6. strcat(full_name, extension);
  7. // ou sprintf(full_name, "%s%s%s", chemin, nom_fichier, extension);


Message édité par olivthill le 08-04-2010 à 14:55:54
n°1982025
ptitchep
Posté le 08-04-2010 à 15:02:43  profilanswer
 

strncpy/strncat éviteront même de dépasser les 250 caractères et d'avoir un comportement indéfini ;-)


---------------
deluser --remove-home ptitchep
n°1982149
Un Program​meur
Posté le 08-04-2010 à 19:12:48  profilanswer
 

ptitchep a écrit :

strncpy/strncat éviteront même de dépasser les 250 caractères et d'avoir un comportement indéfini ;-)


 
A part que strncpy d'une part écrit toujours n caractères et d'autre part ne garanti pas que le résultat soit une chaîne terminée par \0.
strncat est un peu moins piégeux.  La taille disponible à la destination doit être strlen(dst)+n+1.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1982150
404 Not Fo​und
Posté le 08-04-2010 à 19:13:15  profilanswer
 

ptitchep a écrit :

strncpy/strncat éviteront même de dépasser les 250 caractères et d'avoir un comportement indéfini ;-)


 
Jamais vu ça [:lectrodz]

n°1982187
rahela
Posté le 08-04-2010 à 20:36:46  profilanswer
 

Effectivement ça fonctionne!! j'ai tout le chemin affiché ! :D merci à vous !

mood
Publicité
Posté le 08-04-2010 à 20:36:46  profilanswer
 

n°1982231
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 08-04-2010 à 21:38:51  profilanswer
 

404 Not Found a écrit :


 
Jamais vu ça [:lectrodz]


Si l'utilisateur rentre une chaîne de 5000 caractère et que toi tu la strcpy comme un boeuf dans ton buffer de 250 octets ton programme risque de pas aimer. Bon c'est sûr sur une utilisation normale y'aura jamais de problèmes cependant je tends à penser qu'il faut toujours utiliser strncpy en copiant n - 1 caractère (pour laisser de la place au \0) par sécurité :jap:
 
L'autre solution étant de faire un strlen de l'argument passé puis de vérifier si la taille de la chaîne est bien inférieure à la taille du buffer. Ca a l'avantage de pouvoir faire une gestion d'erreur correcte, alors qu'avec un strncpy tu vas juste copier les x premiers caractères et donc peut être tronquer ce que l'utilisateur a rentré :D


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°1982243
ptitchep
Posté le 08-04-2010 à 22:08:08  profilanswer
 

Un Programmeur a écrit :


 
A part que strncpy d'une part écrit toujours n caractères et d'autre part ne garanti pas que le résultat soit une chaîne terminée par \0.
strncat est un peu moins piégeux.  La taille disponible à la destination doit être strlen(dst)+n+1.


Je n'ai pas dit qu'il fallait les utiliser sans se soucier de rien non plus.


---------------
deluser --remove-home ptitchep
n°1982260
Elmoricq
Modérateur
Posté le 08-04-2010 à 22:31:08  profilanswer
 

Sinon y a snprintf() qui est très bien aussi (mais C99, ce qui ne devrait quand même plus trop poser de problème aujourd'hui) : pas besoin de se soucier de la taille du buffer vs. la taille de la chaîne initiale (strncpy), et pas besoin d'initialiser le buffer avant recopie (strncat). Bon, je parle là des tâches communes hein.

 

Mais sinon, je plussoie "Un Programmeur" : strncat est bien moins casse-gueule. À préférer à strncpy, qui est une fonction si fourbe que je me demande qui a bien pu spécifier ce... cette... chose.

Message cité 1 fois
Message édité par Elmoricq le 08-04-2010 à 22:32:26
n°1982361
Un Program​meur
Posté le 09-04-2010 à 09:57:40  profilanswer
 

Elmoricq a écrit :

Mais sinon, je plussoie "Un Programmeur" : strncat est bien moins casse-gueule. À préférer à strncpy, qui est une fonction si fourbe que je me demande qui a bien pu spécifier ce... cette... chose.


 
L'histoire que j'ai lue est qu'elle était conçue pour remplir le champs nom dans la structure décrivant les répertoires des premières versions de Unix, quand les noms étaient limités à 14 caractères (elle n'est pas dans l'index de mon exemplaire du Lions' Commentary on UNIX 6th Edition et j'ai pas cherché dans le code lui-même mais la structure décrivant les répertoires serait bien remplie correctement avec un strncpy).


---------------
The truth is rarely pure and never simple (Oscar Wilde)

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Langage C : concaténation de chaines de caractères

 

Sujets relatifs
le langage linotteQuel langage pour creer ce logiciel ?
Casse-tête... Class Library C++/CLI vers C#?[C] Aide pour mon Puissance 4 ! =)
Comment compiler un fichier C#Divers questions en C
[MYSQL] Lister valeur supérieure ou égale à 8 caractèresComparaison de chaine de caractères / Question à la con
Comptage des voyelles d'une suite de caracteres, plusieurs questions..[C] Récuperer le nom d'un fichier zip
Plus de sujets relatifs à : Langage C : concaténation de chaines de caractères


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR