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 :

couper une chaine de caractère suivant séparateur


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut couper une chaine de caractère suivant séparateur
    Bonsoir à tous, j'ai un petit problème
    Tout d'abords je vous explique le prog

    Je dois rentrée une chaine de caractère de ce style 'a'b'c' 'd'e'f'\0'

    et je doit couper la chaine pour la mettre dans un tableau comme ceci

    T[0] = "abc"
    T[1] = "def"
    T[2] = "NULL"

    j'ai réussit à gérer ceci mais j'ai une erreur au niveau de l'affichage te T

    ceci c'est pour linux enfaite après suivant ce que j'ai comme symbole je vais devoir faire tel ou tel action en schell

    voici le code en entier si vous voulez testé

    le main :

    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
     
    // Giacomoni Jessy et ROUSSET Loïc le 13/12/11
     
    #include "cembarque.h"
     
    /*          Initialisation des variables globales            */
     
     
     
    bool Sortie;
     
    int main(void)
    {
     
    /* Affichage début progr */
     
     
    	printf("par : GIACOMONI J. et ROUSSET L. -- derniere modif le 12/12/2011 \r\n\r\n");
    	printf("\r\n************************** Bienvenu dans le programme **************************\r\n\r\n");
     
    /* Affichage sous prog gestion chaine */
     
    	do
    	{
    		printf("_______________________ SOUS PROG GESTION COUPURE MOT __________________________\r\n");
    		printf("Objectif : ce programme permet de couper des chaines de caracteres en les\r\nplacant dans un tableau. \r\n\r\nComment : Quand un caractere specifique apparait nous devons le supprimer et\r\nordonner les chaines dans le tableau.\r\n\r\n");
    		printf("\r\n------------------------------ DEBUT DU TRAITEMENT -----------------------------\r\n");
     
    		gestionChaine();
     
    		printf("\r\n------------------------------- FIN DU TRAITEMENT ------------------------------\r\n");
    		printf("_____________________ FIN SOUS PROG GESTION COUPURE MOT ________________________\r\n");
     
    		Sortie = reemissionProg();
     
    	} while (Sortie == true);
     
     
    /* Affichage Fin prog */
     
    	printf("\r\n******************************* Fin du programme *******************************\r\n\r\n");
    	getchar();
    	exit(0);
    	return EXIT_SUCCESS;
    }
    Le.H

    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
     
    /* Appels aux bibliothèques*/
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    //#include <stdbool.h>
     
    /* Déclaration sous programme*/
     
     
    void gestionChaine();
    void PurgeStdin();
    char* saisieClavier();
    bool reemissionProg();
    void afficher_mots(char const * const * resultat);
    un sous prog:
    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
     
    // Giacomoni Jessy et ROUSSET Loïc le 13/12/11
    // Ce programme permet de gérer la demande de répétition du programme ou non
     
     
    #include "cembarque.h"
     
    bool reemissionProg()
    {
    	char Commande[1];
    	bool Sortie = false;
     
    	printf("Voulez-vous reexecuter le programme? (O/N) : ");
    	scanf("%c",Commande);
    	PurgeStdin();
     
    	while (Commande[0] != 'O' && Commande[0] != 'N')
    	{
    		printf("\r\nCaractere invalide recommancez\r\n\r\n");
    		printf("Voulez-vous reexecuter le programme? (O/N) : ");
    		scanf("%c",Commande);
    		PurgeStdin();
    	}
     
    	if (Commande[0] == 'O' || Commande[0] == 'N')
    	{
    		if (Commande[0] == 'O')
    		{
    			Sortie = true;
    			printf("\r\n\r\n Appuyer sur Entree pour continuer\r\n\r\n");
    		}	
     
    		else 
    		{
    			Sortie = false; 
    			printf("\r\n\r\n Appuyer sur Entree pour continuer\r\n\r\n");
    		}
    	}
     
    	PurgeStdin();
    	return Sortie;
     
    }
    et les autres

    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    /* Giacomoni Jessy et ROUSSET Loïc le 17/12/11
    permet la découpe d'une chaine de caractère suivant les symbole <  >  &  |  \t  ' '  \0  \n \r
     
    printf : affichage sur la console
    free : libère la mémoire après avoir fait un mallo
     
    */
     
    #include "cembarque.h"
     
     
    /* renvoie un tableau contenant l'ensemble des mots de chaine
    realiser un free sur le premier mot puis sur le resultat de la fonction quand on n'en a plus besoin */
    void gestionChaine()
    {
      unsigned int taille;
      unsigned int nb_mots = 0;
      unsigned int parcourTab, parcourTab2;
      char* texte;
      char** resultat;
     
      char*chaine = saisieClavier();
     
      /* on calcule la taille de chaine et le nombre de mots de chaine */
     
      for(parcourTab = 0; chaine[parcourTab] != '\0'; parcourTab++)
      {
        if((chaine[parcourTab] == ' ') || (chaine[parcourTab] == '<') || (chaine[parcourTab] == '>') || (chaine[parcourTab] == '&') || (chaine[parcourTab] == '|') || (chaine[parcourTab] == '\r') || (chaine[parcourTab] == '\t') || (chaine[parcourTab] == '\n') || (chaine[parcourTab] == '\0'))
          nb_mots++;
      }
      taille = parcourTab;
     
      /* on fait les allocations correspondantes */
     
      texte = (char*) malloc(sizeof(char) * (taille + 1));
      resultat = (char**) malloc(sizeof(char*) * (nb_mots + 1));
     
      /* echecs  */
     
    	if( texte == NULL )
    	{
    		 fprintf(stderr,"Allocation impossible \n");
    		 exit(EXIT_FAILURE);
    	}
     
    	if( resultat == NULL )
    	{
    		 fprintf(stderr,"Allocation impossible \n");
    		 exit(EXIT_FAILURE);
    	}
     
      /* on met le premier mot dans le tableau et on met le dernier mot a NULL pour savoir quand le tableau s'arrete */
     
      resultat[0] = texte + '\0';
      resultat[nb_mots] = NULL;
      texte[taille] = '\0';
     
      /* on copie chaine dans texte en remplacant les espaces par des fins de chaine en ajoutant les debuts de mot a res */
      parcourTab2 = 1;
     
      for(parcourTab = 0; parcourTab < taille; parcourTab++)
      {
        if((chaine[parcourTab] == ' ') || (chaine[parcourTab] == '<') || (chaine[parcourTab] == '>') || (chaine[parcourTab] == '&') || (chaine[parcourTab] == '|') || (chaine[parcourTab] == '\r') || (chaine[parcourTab] == '\t') || (chaine[parcourTab] == '\n') || (chaine[parcourTab] == '\0'))
        {
          texte[parcourTab] = '\0';
          resultat[parcourTab2] = texte + parcourTab + 1;
          parcourTab2++;
        }
        else
          texte[parcourTab] = chaine[parcourTab];
      }
    	afficher_mots(resultat);
    	free(resultat);
    	texte=NULL;
    	free(texte);
     
    }
     
    void afficher_mots(char const * const * resultat)
    {
      unsigned int affichage;
      for(affichage = 0; resultat[affichage] != NULL; affichage++)
        printf("mot %d : %s\n", affichage, resultat[affichage]);
      resultat = NULL;
    }
     
     
    /* Giacomoni Jessy et ROUSSET Loïc le 12/12/11
    PurgeStdin permet de vider le fichier stdin (fichier d'entrée sortie ici pour la saisie clavier)
    utilisation de getchar : permettant de retourné le nombre de caractère*/
     
    void PurgeStdin()
    {
        int c;
     
        c = getchar();
        while ((c != '\0') && (c != '\n'))
            c = getchar();
     
    }
     
     
    /* Giacomoni Jessy et ROUSSET Loïc le 14/12/11
     
    saisieClavier permet de gérer la saisie clavier, (les erreurs ...)
     
    malloc : détermine l'espace mémoire prix par le tableau suivant le nombre de caractère que l'utilisateur souhaite
    getchar : permettant de savoir le nombre de caractère
    printf : affichage sur la console
    scanf : permet de récuper dans une variable ce qu'à entré l'utilisateur (ne prend pas en charge les espaces)
    fgets : idem scanf sauf que l'on peut déliminer la taille que l'on veut récupérer (il prend en charge les espaces)*/
     
     
     
    char *saisieClavier()
    {
     
    /*          Initialisation des variables             */	
     
    	int nbCaract=0;
    	char* text = NULL;
    	char* buffer = NULL;
     
    // Malloc du tableau
     
    	buffer = (char*) malloc(sizeof(char)*(TAILLE));
     
    	if( buffer == NULL )
    	{
    		 fprintf(stderr,"Allocation impossible");
    		 exit(EXIT_FAILURE);
    	}
     
    // Demande saisi d'une phrase dans buffer + déplacement dans text
     
    	printf("\r\nSaisie votre chaine (avec separateur) :\r\nICI ->  \n");  
    	fgets(buffer, TAILLE, stdin);
    	nbCaract = strlen(buffer) - 1;
    	text = (char*) malloc(sizeof(char) * (nbCaract)); 
     
    	if( text == NULL )
    	{
    		 fprintf(stderr,"Allocation impossible");
    		 exit(EXIT_FAILURE);
    	}
     
        PurgeStdin();
    	strcpy(text,buffer);
    	buffer = NULL;
    	free(buffer);
    	printf ("Si la chaine de depart est : %s \n", text);
    	printf ("Le tableau a 2 dimensions sera consitue de : \n");
    	return text;
    }
    il y a 1 semaine le programme coupé bien la chaine mais le prof m'a dit de recommencer et m'a dit c'est pas juste un prog pour couper la chaine

    mais après suivant tes séparateurs tu va faire un traitement donc j'ai recommencé

    dites moi si cela va pour faire du shell après

    merci et oui aussi pouvez vous me dire pourquoi j'ai un problème d'affichage à la fin j'ai un message d'erreur quand je veux affiché RESULTAT[] (le programme s'execute mais plante à la fin)

    merci beaucoup

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Points : 62
    Points
    62
    Par défaut
    salut

    je ne sais pas comment tu veux afficher ta chaine mais je pense que c'est fout ces deux lignes de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for(affichage = 0; resultat[affichage] != NULL; affichage++)
        printf("mot %d : %s\n", affichage, resultat[affichage]);
    ou peut ètre le "%C" au lieu "%S" ? bon chance




    (débutant)

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    non c'est bien un %s j'ai testé

    enfaite en debbug je me suis apperçu qu'il passé une fois de trop dans la boucle alors que j'ai bien précisé qu'il s'arrêté quand on voyé le caractère de fin de chaine

    aidez moi svp merci

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 486
    Points : 13 696
    Points
    13 696
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    En l'état, votre application ne compile pas chez moi (CodeBlocks sous Windows XP). Il me faut faire les modifications suivantes :
    • decommenter la ligne #include <stdbool.h>
    • definir taille (par exemple # define TAILLE 500)


    J'ai aussi un warning :
    D:\TestsC\Decoupage\cembarque.c|125|warning: passing argument 1 of 'afficher_mots' from incompatible pointer type|
    qui me semble important....

    Quelques remarques :
    • tu ne protèges pas ton fichier cembarqu.h contre les inclusions multiples
    • Sortie est une variable globale. Pourtant tu fais Sortie = reemissionProg(); alors même que Sortie est utilisée dans la fonction
    • text = (char*) malloc(sizeof(char) * (nbCaract)); --> buffer est plus long de 1 caractère que text
    • pourquoi faire text ? pourquoi ne pas garder buffer ?
    • les lignes apres /* on met le premier mot dans le tableau et on met le dernier mot a NULL pour savoir quand le tableau s'arrete */ me semblent douteuses...
    • tu calcules une taille de chaine avec un compteur boucle alors que tu peux utiliser strlen

    Ton code est vraiment pas très propre, tu devrais te poser calmement et le relire.

    Autre question : si ça marchait, pourquoi tu n'as pas gardé ce qui marchait ?


    EDIT :
    J'ai oublié de te dire de regarder la fonction strtok : http://man.developpez.com/man3/strtok.3.php

    Ainsi que : alloues-tu la mémoire de chaque élément de ton char** ? (et non le char** lui-même)

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 131
    Points : 33 074
    Points
    33 074
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    ce que je vois c'est que de manière générale tu t'embrouilles dans les tailles des différente chaînes. Et du coup ça engendre des erreurs sur le reste du programme.
    Une chaîne compte N+1 caractère, N caractère "réelles" + '\0' de fin de chaîne
    De la même manière, le nombre de mots dans ta chaîne doit démarrer à 1, parce que tu sortiras de la chaîne sans "compter" le dernier (ou être incrémenté en sortie de boucle)

    Quand je vois resultat[0] = texte + '\0'; euh...
    La concaténation de chaîne en C c'est pas ça ==> voir strcat

    Pourquoi Sortie est globale ? Ca ne me semble pas justifié

    Dans ton 3° code if (Commande[0] == 'O' || Commande[0] == 'N') est toujours vrai, puisque tu arrives ici uniquement si if (Commande[0] != 'O' && Commande[0] != 'N')
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      for(parcourTab = 0; parcourTab < taille; parcourTab++)
      {
        if((chaine[parcourTab] == ' ') || (chaine[parcourTab] == '<') || (chaine[parcourTab] == '>') || (chaine[parcourTab] == '&') || (chaine[parcourTab] == '|') || (chaine[parcourTab] == '\r') || (chaine[parcourTab] == '\t') || (chaine[parcourTab] == '\n') || (chaine[parcourTab] == '\0'))
        {
          texte[parcourTab] = '\0';
          resultat[parcourTab2] = texte + parcourTab + 1;
          parcourTab2++;
        }
        else
          texte[parcourTab] = chaine[parcourTab];
      }
    les bornes sont fausses puisque tes tailles sont faussées dès le début

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	texte=NULL;
    	free(texte);


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	buffer = NULL;
    	free(buffer);
    re

    Ton code est vraiment pas très propre, tu devrais te poser calmement et le relire.
    si ça marchait, pourquoi tu n'as pas gardé ce qui marchait ?
    et as-tu toujours le code qui fonctionnait comme référence ou nouveau départ possible ?

    Bonne chance

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 486
    Points : 13 696
    Points
    13 696
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	texte=NULL;
    	free(texte);


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	buffer = NULL;
    	free(buffer);
    re
    J'ai eu la flemme de rééditer mon message pour parler de ça.... Bousk a raison de le signaler. Voir http://man.developpez.com/man3/free.3.php :

    void free (void * ptr);

    [...]

    free() libère l'espace mémoire pointé par ptr, qui a été obtenu lors d'un appel antérieur à malloc(), calloc() ou realloc(). Si le pointeur ptr n'a pas été obtenu par l'un de ces appels, ou si il a déjà été libéré avec free(), le comportement est indéterminé. Si ptr est NULL, aucune tentative de libération n'a lieu.
    C'est logique : ton pointeur est nul et ne pointe sur rien, il n'y a donc aucune zone à libérer. Ta zone précédemment allouée est définitivement perdue dans les limbes de ton tas.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2011
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    bonjour et merci beaucoup. tout fonctio
    nne a merveille grace a vous merci beaucoup et bonne fete

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 486
    Points : 13 696
    Points
    13 696
    Billets dans le blog
    1
    Par défaut
    De rien et bonnes fêtes à toi

    Marque le sujet comme résolu si tout est OK.

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 10/02/2009, 10h31
  2. Réponses: 6
    Dernier message: 15/04/2007, 14h06
  3. couper une chaine de caractère en deux ?
    Par fmh1982 dans le forum C++
    Réponses: 3
    Dernier message: 31/03/2007, 19h17
  4. Couper une chaine de caractères
    Par perldebutant dans le forum Langage
    Réponses: 2
    Dernier message: 13/07/2006, 01h06
  5. Couper une chaine de caractère
    Par Spacio dans le forum Access
    Réponses: 2
    Dernier message: 28/06/2006, 19h06

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