Chaine de caractere en c aidez moi SVP

Fermé
rimounatn Messages postés 93 Date d'inscription jeudi 24 décembre 2009 Statut Membre Dernière intervention 7 septembre 2010 - 17 janv. 2010 à 19:26
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 18 janv. 2010 à 21:40
Bonjour,
j'ai un projet en c (voyageur de commerce) que je dois le compléter aujourd'hui et j'ai un problème c'est que :
je veux réalisé une fonction qui prend en paramètres une 2chaine de caractères : la premiere est une chaine qui represente le nom d'un fichier (exple:idInstance.tsp) , et la deuxieme une autre chaine (exple : .tour)
ma fonction doit renvoyé une chaine construite de ces deux dernières chaine de la façon suivante:
prendre la partie juste avant le point de la 1ere chaine c'àd idInstance et la concaténé avec la deuxième chaine, de façon à avoir à la fin "idInstance.tour"
j'ai essayé de faire mon exercice toute seule mais malheureusement que ca fonctionne pas et que j'ai une erreur de segmentation ,voici mon code:
void ma_fonction(char chaine1[], char chaine_finale[], char chaine2[])
{
      int i=0;
      char * ch;
     while(chaine1[i]!='.')
     {
        i++;
     }
     strncpy(ch,chaine1,i); // pour copier la partie de chaine1 de 0 à i dans  ch 
     strcat( chaine_finale,ch);// pour concat de ch à chaine_finale
     strcat( chaine_final,chaine2);//  pour concat de chaine2 à chaine finale
}

et pour l'appel au niveau de main():
char chaine_finale[200];
ma_fonction(argv[2],chaine_finale,".tour");
aidez moi svpp :(
A voir également:

6 réponses

Bonjour

strncpy(ch,chaine1,i);
Cette ligne ne peut pas marcher car ch est un pointeur non initialisé, donc tu recopies n'importe où dans la mémoire. L'erreur de segmentation est garantie.
Comme tu veux recopier i caractères, tu as besoin de i+1 octets (ne pas oublier le 0 final). Il faut donc allouer une zone de i+1 octets et faire pointer ch dessus, ce qui se fait par :
ch = (char *)malloc(i+1);
juste avant le
strncpy(ch,chaine1,i); //
et ne pas oublier le 0 final
ch[i]=0;
et ne pas oublier à la fin de la fonction de libérer la mémoire alloué :
free(ch);
0
rimounatn Messages postés 93 Date d'inscription jeudi 24 décembre 2009 Statut Membre Dernière intervention 7 septembre 2010 15
17 janv. 2010 à 20:00
salut,
merci beaucoup de me répondre, mais je m'excuse j'ai pas bien compris ta réponse , vous voulez me dire que j'ecri ca ?
:
void ma_fonction(char chaine1[], char chaine_finale[], char chaine2[])
{
int i=0;
char * ch;
ch[i]=0;
while(chaine1[i]!='.')
{
i++;
}
ch= (char*) malloc( (i+1)*sizeof(char));
strncpy(ch,chaine1,i); // pour copier la partie de chaine1 de 0 à i dans ch
strcat( chaine_finale,ch);// pour concat de ch à chaine_finale
strcat( chaine_final,chaine2);// pour concat de chaine2 à chaine finale
free(ch);
}
En faite je connait bien que le sizeof char=1 octet ;)
bon je veux juste savoir si j'ai bien compri ta reponse ou pas , parceque j'ai essayé ca et ca ne foncionne pas encore et j'ai encore la meme errur de sgmentation :((((
0
Tu as mal lu ma réponse
Il manque le ch[i]=0
car strncpy(ch,chaine1,i) ne met pas automatiquement de 0 à la fin de la chaîne
donc le strcat qui suit va écrire... on ne sait pas où
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
17 janv. 2010 à 23:19
Salut,
Si, strncpy met automatiquement le '\0' mais pas systématiquement. Le seul cas où il ne le met pas c'est lorsque i est supérieur à la taille de ch. Et ce cas-là, il faut mettre un if explicite car sinon les strcat suivant vont provoquer un buffer overflow.
Mais je conseille plutôt d'utiliser strncat que strcat.
Cdlt,
0
le père > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
18 janv. 2010 à 13:51
Pas du tout d'accord :)
strncpy recopie au plus i caractères. Sans rien ajouter a priori. strncpy ne complètera avec des 0 que s'il en a besoin pour arriver à i caractères, c'est à dire si la chaine source est trop courte, donc si i est supérieur à la longueur de la source - exactement le contraire de ce que tu dis. Et dans le cas de rimounatn, i est inférieur à la longueur de la chaine source dans la mesure où il a trouvé un '.' dans nom_fich, ce qui est pour lui le cas normal. Donc normalement pour lui le 0 n'a pas été recopié et il faut qu'il le rajoute "à la main"

références :
http://www.cplusplus.com/reference/cstring/strncpy/
ou
http://www.elook.org/programming/c/strncpy.html
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844 > le père
18 janv. 2010 à 21:40
strncpy ne complètera avec des 0 que s'il en a besoin pour arriver à i caractères
Oui c'est pour ça que je dis automatiquement mais pas systématiquement.
Mais, ce que je voulais dire par dessus tout c'est que dans le cas où il n'y aurait pas de '\0' de rajouté à la fin de la chaîne c'est que la chaîne de destination ne serait pas assez grande, et dans ce cas il faut surtout ne pas mettre de strcat.
C'est pour ça que l'idée de rajouter un '\0' après le strncpy est très bon, et même obligatoire, mais dans ce cas, il faut faire un if pour savoir si on peut continuer avec une concaténation derrière.

De même qu'il est dommage d'utiliser strncpy et de casser le contrôler avec un strcat au lieu de strncat.

Cdlt,
0
rimounatn Messages postés 93 Date d'inscription jeudi 24 décembre 2009 Statut Membre Dernière intervention 7 septembre 2010 15
17 janv. 2010 à 23:11
j'ai essayé ce code et ca fonctionne pour une partie et pas pour l'autre , j'espere que tu poura m'aidé Stp et merci de me reponde
void nom_fichier(char nom_fich[],char reste_nom[],char nom_final[])
{
   int i=0;
   char ch1[] = "" ;
   nom_final="";
   
  while(nom_fich[i]!='.')
  { 
    i++;
    printf("%d",i);
    
  }
    

    strncat(ch1 ,nom_fich, i);
    strcat(ch1,reste_nom);
    printf("apres1 :%s\n" ,ch1);


strcpy(nom_final,ch1);
printf("nom_final: %s",nom_final);


  
}

et voici ce ke j'ai mis ds mon main( ):
char chaine2[]=".tour";
char chaine1[222];
strcpy(chaine1,argv[2]);
char nom_final[100];
nom_fichier(chaine1,chaine2,nom_final);

j'ai un pb "erreur de segmentation, tout va bien juste la partie du code en gras , mais moi je veux avoir une chaine contenant "idInstance.tour" contenu ds chaine_final .pourque je puisse l'utilisé au niveau de mon main pour creer un fichier ayant ce nom ;))))
g confiance en vous ;)) aidez moi SVp
Configuration: Linux Fedora
Firefox 2.0.0.8
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Autre problème : quelle est la taille de chaine_finale ? S c'est en fait un pointeur non initialisé, tu as le même problème. Et si sa taille est inférieure à i+1+ taille (chaine_2), ça va encore déborder.
Encore un autre : tu fais strcat( chaine_finale,ch); mais il faudrait initialiser chaine_finale avec un caractère nul ou faire un strcpy plutôt qu'un strcat.

En fait en relisant, je me demande à quoi sert ta variable ch. Tu peux bien agir directement sur chaine_finale, pas besoin d'un buffer intermédiaire
0
rimounatn Messages postés 93 Date d'inscription jeudi 24 décembre 2009 Statut Membre Dernière intervention 7 septembre 2010 15
17 janv. 2010 à 23:23
merci encore, mais je débute en c et j'ai tjrs des problemes avec les pointeurs , excuse moi , pouvez vous me dire comment je l'intialise ma chaine_final ?et où ?dans le main?ou dans la fonction ?
la taille de cette chaine elle va pas repassé 50 caractères au plus .
je te jure je vais pleuré ;( aide moi svp .
svp vous pouvez recopié mon code et mettre l'initialisation de cahaine finale comme ca il va etre claire pour moi :( merciiiiiiiiiiiii d'avance
0