IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème comparaison de chaînes via realloc


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Par défaut Problème comparaison de chaînes via realloc
    Bonjour,

    J'ai un problème sur un de mes programmes, j'ai besoin de votre aide je ne trouve pas la solution.
    Je vous explique le principe j'ai deux chaines sous cette forme :
    toto, tata, titi, jean-jacque,
    foot, basket, hand,

    L'ajout de ces chaines se réalise à l'aide de reallocs().
    J'ai fais une fonction qui compare ces deux chaines -> int compare_chaine(char * premiere, char * seconde);
    Ma fonction compte le nombre d'éléments dans chaque chaînes, si premiere < seconde la fonction renvoie 1 cela veut dire que le nombres d'éléments est inférieur dans ma chaine premiere. Sinon ma fonction renvoie 0.

    Ce bout de code fonctionne mais le problème est qu'à la suite de l’exécution de compare_chaine, cela modifie completement ma chaine de départ (premiere) et j'ai besoin de cette chaine dans mon programme principal pour réaliser d'autres traitement dessus.

    Illustration de mon problème :
    Nom : Resultat_Execution.png
Affichages : 93
Taille : 38,1 Ko


    Voici mon Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /* Déclaration du prototypes des fonctions : */
    char * ajout_chaine(char *attribut);
    int compare_chaine(char * premiere, char * seconde);
     
    int main(void)
    {
    	char *premiere = NULL; 
    	char *seconde = NULL;
    	premiere = ajout_chaine("");//Ajout du premier champs vide nécessaire pour pouvoir imbriquer les autres chaines et éviter le warning
    	seconde = ajout_chaine("");
     
    	char toto[5] = "toto";
    	toto[5] = '\0';
    	premiere = ajout_chaine(strcat(premiere,toto));
    	char basket[7] = "basket";
    	basket[7] = '\0';
    	premiere = ajout_chaine(strcat(premiere,basket));
    	char tshirt[7] = "tshirt";
    	tshirt[7] = '\0';
    	premiere = ajout_chaine(strcat(premiere,tshirt));
     
    	printf("Premiere -> %s\n", premiere);
     
    	char titi[5] = "";
    	titi[5] = '\0';
    	seconde = ajout_chaine(strcat(seconde,titi));
    	char football[9] = "";
    	football[9] = '\0';
    	seconde = ajout_chaine(strcat(seconde,football));
    	char lalal[7] = "";
    	lalal[7] = '\0';
    	seconde = ajout_chaine(strcat(seconde,lalal));
    	char llololo[7] = "";
    	llololo[7] = '\0';
    	seconde = ajout_chaine(strcat(seconde,llololo));
     
    	printf("seconde -> %s\n", seconde);
     
    	printf("premiere AVANT -> [ %s ]\n", premiere);
     
    	printf(" \nResultat -> %d \n", compare_chaine(premiere, seconde)); 
     
    	printf("premiere APRES -> [ %s ]\n Modification de ma chaine Problème ...\n", premiere);
    	return 0;
    } /* Fin main() */
     
    char * ajout_chaine(char *attribut)
    {
    	char *maChaine = NULL;
     
    	maChaine = realloc(maChaine, 100);
    	strcpy(maChaine,attribut);
    	//printf("maChaine -> [  %s  ]\n\nattribut -> [  %s  ]\n\n",maChaine, attribut);
    	strcat(maChaine,",");
     
    	return maChaine;
    } /*Fin Ajout_chaine */
     
    int compare_chaine(char * premiere, char * seconde) // Si c'est la premiere et premiere = seconde on retourne 1 sinon on retourne 0
    {
    	int i = 0, n = 0;
    	char caractereSpecial[1] = ",";
    	char *recup;
     
    	recup = strtok(premiere, caractereSpecial);
    	while( recup != NULL)
    	{
    		//printf("premiere -> [ %s ]\n", recup);
    		recup = strtok(NULL, caractereSpecial);
    		i++;
    	}
     
    	recup = strtok(seconde, caractereSpecial);
    	while( recup != NULL)
    	{
    		//printf("seconde -> [ %s ]\n", recup);
    		recup = strtok(NULL, caractereSpecial);
    		n++;
    	}
     
     
    	printf(" premiere -> [ %d ]\nseconde -> [ %d ]\n", i, n);
     
     
    	if(i<n)
    	{
    		return 1;
    	}
     
    	else
    	{
    		return 0;
    	}
     
     
    } /* Fin compare_chaine */
    Merci pour votre aide en espérant avoir été assez rigoureux dans mon explication. Je ne comprends pas pourquoi cela modifie ma chaine c'est sans doute à cause de la fonction strtok().

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Si tu veux comparer des chaines, il n'y a aucune raison qu'elles soient modifiable.
    Il faut que ta fonction compare_chaine prennent deux char const * en arguments.

    Par ailleurs, strtok modifie la chaine sur laquelle elle est appelée, il faut donc en faire une copie.
    il y a strncpy pour ca.

    (sauf si ma mémoire me fait défaut, je fais surtout du C++, ces temps-ci)

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Par défaut
    Citation Envoyé par leternel Voir le message
    Si tu veux comparer des chaines, il n'y a aucune raison qu'elles soient modifiable.
    Il faut que ta fonction compare_chaine prennent deux char const * en arguments.

    Par ailleurs, strtok modifie la chaine sur laquelle elle est appelée, il faut donc en faire une copie.
    il y a strncpy pour ca.

    (sauf si ma mémoire me fait défaut, je fais surtout du C++, ces temps-ci)
    Salut,

    Merci de ta réponse rapide !

    Dans mon programme je fais déjà des copies ça marche mais dans ce cas (ci-dessous) précis où j'ai plusieurs conditions qui se succèdent ça ne marche pas.

    Ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if(compare_chaine(compareDisplay, compare) == 1) //Si compareDisplay < compare 
    {
    	/* Mon traitement */
    }
     
    else if( compare_chaine(compareDisplay, compare) == 0) // Si compareDisplay > compare
    {
    	/* Deuxième traitement mais ça ne peut pas marcher compareDisplay viens d'être modifier à cause de la première instruction */
    }
    Il faut que je trouve une autre solution le strtok est bien mais pas dans mon cas j'ai l'impression .

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Cela ne te paraît-il pas bizarre, une fonction appelée ajout_chaine qui ne prend qu'un seul paramètre?

    Si tu veux concaténer deux chaînes, tu dois prendre deux paramètres:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    char* ajout_chaine(char const *s1, char const *s2)
    {
    	size_t length1 = 0, length2 = 0, totalLength = 0;
    	size_t totalSize = 0, currentOffset = 0;
    	char *ret = NULL;
    	/*Calcul de la taille totale du buffer en sortie*/
    	if(s1 != NULL)
    		length1 = strlen(s1);
    	if(s2 != NULL)
    		length2 = strlen(s2);
    	totalLength = length1 + length2;
    	totalSize = totalLength + 1;
     
    	/*Allocation du buffer*/
    	ret = malloc(totalSize * sizeof *ret);
    	if(ret != NULL)
    	{
    		/*Remplissage du buffer*/
    		if(s1 != 0)
    			strcpy(ret+currentOffset, s1);
    		currentOffset += length1;
    		if(s2 != 0)
    			strcpy(ret+currentOffset, s2);
    		currentOffset += length2;
    		ret[currentOffset] = '\0';
    	}
    	return ret;
    }
    Et si tu veux mettre une virgule entre deux, tu fais la même chose pour trois:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    char* ajout_chaine3(char const *s1, char const *s2, char const *s3)
    {
    	size_t length1 = 0, length2 = 0, length3 = 0, totalLength = 0;
    	size_t totalSize = 0, currentOffset = 0;
    	char *ret = NULL;
    	/*Calcul de la taille totale du buffer en sortie*/
    	if(s1 != NULL)
    		length1 = strlen(s1);
    	if(s2 != NULL)
    		length2 = strlen(s2);
    	if(s3 != NULL)
    		length3 = strlen(s3);
    	totalLength = length1 + length2 + length3;
    	totalSize = totalLength + 1;
     
    	/*Allocation du buffer*/
    	ret = malloc(totalSize * sizeof *ret);
    	if(ret != NULL)
    	{
    		/*Remplissage du buffer*/
    		if(s1 != 0)
    			strcpy(ret+currentOffset, s1);
    		currentOffset += length1;
    		if(s2 != 0)
    			strcpy(ret+currentOffset, s2);
    		currentOffset += length2;
    		if(s3 != 0)
    			strcpy(ret+currentOffset, s3);
    		currentOffset += length3;
    		ret[currentOffset] = '\0';
    	}
    	return ret;
    }
    Et encore, ce n'est même pas le plus efficace, vu que ça réalloue un nouveau buffer à chaque fois. Mais au moins, c'est sûr et plus facile à comprendre qu'une fonction qui gère en plus la taille du buffer.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. [Lazarus] Problème de comparaison de chaînes
    Par ChPr dans le forum Lazarus
    Réponses: 3
    Dernier message: 07/06/2013, 15h43
  2. Problème de comparaison de chaînes de caractères
    Par Ayelve dans le forum VC++ .NET
    Réponses: 3
    Dernier message: 15/09/2008, 21h58
  3. [MySQL] Problème de comparaison de chaîne de caractères
    Par Laurent64 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 15/05/2007, 19h04
  4. Problème sur des chaînes de caractères
    Par Anonymous dans le forum Access
    Réponses: 9
    Dernier message: 16/09/2005, 08h21
  5. Problème de type chaîne
    Par champijulie dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 12/05/2005, 20h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo