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 :

[débogage] Découper une chaine puis placer les sous-chaines dans un tableau


Sujet :

C

  1. #1
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut [débogage] Découper une chaine puis placer les sous-chaines dans un tableau
    Bonjour,

    Tous est dans le titre ...
    Je vous donne l'allure de la chaine :
    char* returnValue="nom1\tval1\nnom2\tval2\n..."
    Je récupère cette variable après l'appel à une fonction.

    Je souhaiterais récuperer uniquement les nom et les placer dans un tableau.
    Le tout dynamiquement.

    J'ai un code, que j'esperais efficace, qui ne l'est pas. A chaque appel ma chaine se dégrade, les données deviennent hasardeuses, je ne sais pas ou ca coince.

    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
     
    char **tab = NULL;
    int i=0;
    char *tmp = NULL;
    size_t posT;
    size_t posN;
     
    while(returnValue!=NULL){
    	posT=strcspn(returnValue,"\t");
    	if( ( tab = (char**) realloc (tab, (i+1)*sizeof(char*)) ) == NULL || (tab[i]=(char*)malloc(posT+1)) == NULL){
    	      fprintf (stderr, "Memoire insuffisante\n");
    	      free (tab);
    		tab = NULL;
    		exit (EXIT_FAILURE);
    	}
     
    	strncpy(tab[i],returnValue,posT);
    	PA_Alert(tab[i]);
    	posN = strcspn(returnValue,"\n");
    	size_t sub = strlen(returnValue)-posN;
     
    	if(sub==0){
    		free(returnValue);
    		returnValue=NULL;
    	}else{
    		tmp=(char*)malloc(strlen(returnValue)+1);
    		strcpy(tmp,returnValue);
    		size_t test2 = strlen(tmp);
    		free(returnValue);
    		returnValue=NULL;
    		returnValue = (char *)malloc(sub);
    		int j;
    		for(j=0;j<sub;j++){
    			if(j==sub-1) returnValue[j]="\0";
    			else returnValue[j]=tmp[j+posN+1];
    	}
    	free(tmp);
    	tmp = NULL;
    	i++;
    }
    Si vous avez une idée ...

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PKO06
    J'ai un code, que j'esperais efficace, qui ne l'est pas. A chaque appel ma chaine se dégrade, les données deviennent hasardeuses, je ne sais pas ou ca coince.
    Ce code ne compîle pas. Il est incomplet.

  3. #3
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Effectivement ce n'était qu'un morceau du code, avec en plus une méthode d'une obscure API.

    Voila quelque chose de complet et d'un peu commenté.

    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
     
    #include <stdio.h>
     
    int main (int argc, const char * argv[]) {
    	/*allure de la chaine à parser, retournée par une fonction du vidal, \t0 toujours constater
    	mais ce n'est pas une règle*/
    	char* returnValue="iode\t0\niodixanol\t0\niodochlorhydroxyquin\t0\niodium\t0\n";
    	char **tab = NULL;
    	int i=0;
    	char *tmp = NULL;
    	size_t posT;
    	size_t posN;
     
    	while(returnValue!=NULL){
    		posT=strcspn(returnValue,"\t");
    		if( ( tab = (char**) realloc (tab, (i+1)*sizeof(char*)) ) == NULL || (tab[i]=(char*)malloc(posT+1)) == NULL){
    			fprintf (stderr, "Memoire insuffisante\n");
    			free (tab);
    			tab = NULL;
    			exit (0);
    		}
    		//Copie de la sous chaine dans le tableau
    		strncpy(tab[i],returnValue,posT);
    		posN = strcspn(returnValue,"\n");
    		size_t sub = strlen(returnValue)-posN;
     
    		if(sub==0){
    			free(returnValue);
    			returnValue=NULL;
    		}else{
    			tmp=(char*)malloc(strlen(returnValue)+1);
    			strcpy(tmp,returnValue);
    			free(returnValue);
    			returnValue=NULL;
    			returnValue = (char *)malloc(sub);
    			int j;
    			/*On supprime de la chaine la sous chaine déjà traitée 
                      -> ca bug à ce niveau*/ 
    			for(j=0;j<sub;j++){
    				if(j==sub-1) returnValue[j]="\0";
    				else returnValue[j]=tmp[j+posN+1];
    			}
    		}
    		free(tmp);
    		tmp = NULL;
    		i++;
    	}
    	int k=0;
    	for(k=0;k<i;k++){
    		printf("%s",tab[i]);
    	}
    	return 0;
    }
    Je ne sais pas si je m'y prend bien...

    edit :

    Un problème déjà ici : je prévois de terminer ma nouvelle chaine returnValue par un "\0". En revanche quand je suis en debogage c'est le caractère "\xfc" qui est ajouté. Je ne connais pas ce caractère (échappement ?).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for(j=0;j<sub;j++){
    	if(j==sub-1) returnValue[j]="\0";
    	else returnValue[j]=tmp[j+posN+1];
    }
    edit bis :

    En ajoutant '\0' cela fonctionne beaucoup mieux : constante de type caractère. Désolé de vous exposer mes lacunes.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PKO06
    Effectivement ce n'était qu'un morceau du code, avec en plus une méthode d'une obscure API.

    Voila quelque chose de complet et d'un peu commenté.
    Euh bof...
    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
     
    Project   : Forums
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `main':
    main.c:7: warning: initialization discards qualifiers from pointer target type
    main.c:15: warning: implicit declaration of function `strcspn'
    main.c:16: warning: implicit declaration of function `realloc'
    main.c:16: warning: implicit declaration of function `malloc'
    main.c:18: warning: implicit declaration of function `free'
    main.c:20: warning: implicit declaration of function `exit'
    main.c:23: warning: implicit declaration of function `strncpy'
    main.c:25: warning: implicit declaration of function `strlen'
    main.c:32: warning: implicit declaration of function `strcpy'
    main.c:39: warning: comparison between signed and unsigned
    main.c:40: warning: comparison between signed and unsigned
    main.c:40: warning: assignment makes integer from pointer without a cast
    main.c: At top level:
    main.c:4: warning: unused parameter 'argc'
    main.c:4: warning: unused parameter 'argv'
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 3 seconds)
    0 errors, 14 warnings
    Ecrire du C est un processus qui demande rigueur et maitrise... On en est loin...

    Essaye d'écrire du code correct, ça éliminera déjà un certain nombre de comportements indéfinis... Et si ton compilateur ne dit rien essaye de le configurer correctement :

    http://emmanuel-delahaye.developpez....tm#cfg_compilo

  5. #5
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    En effet, tu n'était pas le seul à avoir raison, les résultats le prouvent, mon code n'est pas correct. Lors du test avec la chaine renvoyée que je dois traiter, les résultats sont a nouveaux incohérents. Dans cette chaine il y à des espaces et des caractères accentués que je n'avais pas inclut dans ma chaine de test.

    J'envois tout de même mon code à nouveau. S'il vous sentais encore l'envie de m'aider.

    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
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
     
     
    int main (int argc, const char * argv[]) {
    	/*allure de la chaine à parser, retourner par une fonction du vidal, \t0 toujours constater
    	mais ce n'est pas une règle*/
    	char* returnValue="iode\t0\niodixanol\t0\niodochlorhydroxyquin\t0\niodium\t0\niodoioihlène = clid\t0\narponèle = titi\t0\nzfuzeifuhbèdub = dkzfubdbi\t0\n";
    	char **tab = NULL;
    	int i=0;
    	char *tmp = NULL;
    	size_t posT;
    	size_t posN;
     
    	while(returnValue!=NULL){
    		posT=strcspn(returnValue,"\t");
    		if( ( tab = (char**) realloc (tab, (i+1)*sizeof(char*)) ) == NULL || (tab[i]=(char*)malloc(posT+1)) == NULL){
    			fprintf (stderr, "Memoire insuffisante\n");
    			free (tab);
    			tab = NULL;
    			exit (0);
    		}
    		//Copie de la sous chaine dans le tableau
    		strncpy(tab[i],returnValue,posT);
    		posN = strcspn(returnValue,"\n");
    		size_t sub = strlen(returnValue)-posN;
     
    		if(sub==0){
    			free(returnValue);
    			returnValue=NULL;
    		}else{
    			tmp=(char*)malloc(strlen(returnValue)+1);
    			strcpy(tmp,returnValue);
    			free(returnValue);
    			returnValue=NULL;
    			returnValue = (char *)malloc(sub-1);
    			int j;
    			//On supprime de la chaine la sous chaine déjà traitée
    			for(j=0;j<sub;j++){
    				if(j==sub-1) returnValue[j]='\0';
    				else returnValue[j]=tmp[j+posN+1];
    			}
    			free(tmp);
    			tmp = NULL;
    			i++;
    		}
    	}
    	tab[i]=NULL;
    	int k=0;
    	for(k=0;k<i;k++){
    		printf("%s\n",tab[k]);
    	}
    	return 0;
    }
    J'ai ajouté les headers, il n'y a plus de warning, je vais tout de suite mieux me documenter sur mon IDE XCode. Je suis preneur pour toutes pistes ... merci.

  6. #6
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Visiblement ce ne sont pas les warnings qui sont à la source de l'erreur.
    J'ai converti i et j en unsigned int, fait les initialisation au début ...

    Les problèmes ce sont les éspaces et les caractères accentués.
    Mais je ne sais pas ce pourquoi...

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    une question..

    Que fait le 0 dans ton "...\t0\n..." ???

  8. #8
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    La chaine que je souhaite découpée est retournée par une fonction qui renvoit une liste de substances et le type qualifiant.

    (strTermeQualifiant <HT> strTypeQualifiant <LF>) * n

    HT = tabulation = \t
    LF = newline = \n

    \t0\n : qualifiant = 0

    Le problème vient bien des caractères accentués :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (strTermeQualifiant <HT> strTypeQualifiant <LF>) * n
    le è majuscule sera remplacé par \xc3\xa84 me comptant 3 caractères ...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Une sombre histoire d'UTF-8 ?
    C'est généralement la cause de la transformation d'une lettre accentuée en plusieurs caractères...

  10. #10
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Oui c'est surement ça.
    Je site une phrase lue dans wikipedia :

    "Les caractères sont représentés en UTF-8 par des séquences d'octets de taille variable, ce qui rend certaines opérations sur les chaînes de caractères plus compliquées : le calcul du nombre de caractères ; le positionnement à une distance donnée dans un fichier texte et en règle générale toute opération nécessitant l'accès au caractère de position N dans une chaîne."

    Je ne vois pas comment faire.
    Il y a bien *strchr qui retourne un pointeur sur la première occurence mais comment puis je m'en servir ?

    edit : Le problème venait du fait que les chaines que je copié dans le tableau n'était pas terminé par '\0'.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] extraire une sous chaine puis la convertir en float
    Par aounidevlop dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 18/01/2015, 15h59
  2. [Débutant] découper une image en suivant les contours externes seulement
    Par kbazin dans le forum Images
    Réponses: 10
    Dernier message: 03/08/2010, 16h12
  3. Placer les points contenus dans un tableau sur un graphe
    Par SandyF dans le forum Windows Forms
    Réponses: 4
    Dernier message: 11/09/2009, 17h40
  4. Réponses: 1
    Dernier message: 17/06/2009, 20h30
  5. Optimisation d'une fonction de découpage en sous-chaine
    Par FabaCoeur dans le forum Général Java
    Réponses: 9
    Dernier message: 05/01/2008, 14h00

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