Forum Programmation.c Extraction sous-chaînes

Posté par  .
Étiquettes : aucune
0
6
fév.
2006
Bonjour,

Je voudrais extraire des sous-chaînes via un délémiteur.
J'ai pensé utiliser strtok.
Le problème est que strtok renvoi un pointeur et que je voudrais créer une fonction qui me renvoi un tableau.
Genre :

int main(){
char msg[] = "|15236|termtoacq|125,23|123456789123|\n";
char del[] = "|";
msg_intercept(msg, del);
return 0;
}

char msg_intercept(char * msg, char * del){
char * p;
int i;
char * tab[4];
int nbr = sizeof(tab) / sizeof(* tab);
p = strtok(msg, del);
if (p != NULL) {
puts(p);
tab[0] = p;
for(i=1; ((p = strtok(NULL, del)) != NULL) && i < nbr; i++) {
puts(p);
tab[i] = p;
}
}
return tab;
}


Comment récupérer le tableau dans le main() ? Si cela est possible ?

Si quelqu'un a une autre méthode pour extraire les sous-chaînes, elle est la bienvenue ;)

Merci
  • # référence

    Posté par  . Évalué à 2.

    Tu dois pouvoir retourner une référence vers le tableau.
  • # regarde g_strsplit

    Posté par  (site web personnel) . Évalué à 4.

    glib possède une fonction qui fait ça :

    gchar** g_strsplit (const gchar *string,
    const gchar *delimiter,
    gint max_tokens);

    Tu peux regarder le code correspondant dans glib/gstrfuncs.c
  • # il faut passer le tableau en reference

    Posté par  . Évalué à 2.

    tu ne peux pas recuperer le tableau depuis la fonctions : qd tu sors de msg_intercept () , le tableau n'existe plus.
    il faut le passer en parametre ainsi que sa taille.

    #include <string.h>
    #include <stdlib.h>
    void msg_intercept(char * msg, char * del, char ** tab, int nbr){

    char * p;

    int i;

    printf ("msg_intercept nbr=%d\n", nbr);
    printf ("msg_intercept tab=%d\n", sizeof(tab));

    p = strtok(msg, del);

    if (p != NULL) {

    puts(p);

    tab[0] = p;

    for(i=1; ((p = strtok(NULL, del)) != NULL) && i < nbr; i++) {

    puts(p);

    tab[i] = p;

    }

    }

    }

    int main(){

    char msg[] = "|15236|termtoacq|125,23|123456789123|\n";

    char del[] = "|";

    char * tab[4];
    int i = 0;

    int nbr = sizeof(tab)/sizeof (char *) ; // ou nbr =4 tout simplement

    printf ("tab=%d\n", sizeof(tab));

    msg_intercept(msg, del, &tab[0], nbr);


    for (i =0 ; i<4 && tab[i]!= 0; i++){

    printf ("tab[%d]=\"%s\"\n", i, tab[i]);
    }

    return 0;

    }
    • [^] # Re: il faut passer le tableau en reference

      Posté par  . Évalué à 2.

      Bonjour,

      Je tiens à vous remercier pour vos idées.
      J'ai opté pour la solution du tableau par référence car j'étais parti dans cette optique là.

      Le seul problème est que je voulais absolument retourner un tableau.
      Mais par référence bien plus simple.

      msg_intercept(msg, del, &tab[0], nbr);

      Pourquoi on ne peut pas faire cela :
      msg_intercept(msg, del, &tab, nbr);

      Le pointeur doit être indiqué au début du tableau avec &tab[0] c'est bien ça ?
      • [^] # Re: il faut passer le tableau en reference

        Posté par  . Évalué à 1.

        je n'ai moi meme jamais tres bien compris cet emmerdement.

        si tu fais &tab c''est une reference a un tableau de 4 pointeurs, donc il faut que la fonction ait un prototype :
        msg_intercept(char * msg, char * del , char *tab[4])

        ce qui est penible

        donc on passe &tab[0] qui est un l'adresse d'un pointeur . Donc la fonction peut etre :
        msg_intercept(char * msg, char * del , char **tab, int nb)

        et tab peut etre de n'importe quelle taille.

        sizeof (tab ) = 16 dans main() car c'est un tableau de 4 pointeurs
        sizeof (tab) =4 dans msg_intercept car c'est un pointeur.
        • [^] # Re: il faut passer le tableau en reference

          Posté par  . Évalué à 1.

          si tu fais &tab c''est une reference a un tableau de 4 pointeurs, donc il faut que la fonction ait un prototype :
          msg_intercept(char * msg, char * del , char *tab[4])

          ce qui est penible

          Plus que la pénibilité, c'est la sécurité du code qui est en jeu: à moins que je ne me trompe lourdement, tu peux bien passer un tableau de n'importe quelle taille à ta fonction, il n'y a pas de contrôle (imposé par la norme, s'entend). D'où des problèmes si tu veux accéder à tab[3] alors que tu lui as passé un tableau de taille 2, ou si tu lui as passé un tableau de taille 6... (mais peut-être je me trompe; j'ai peut-être confondu avec les cas void f(char *str) et void f(char str[4])).

          Donc la fonction peut etre :
          msg_intercept(char * msg, char * del , char **tab, int nb)
          Ou, en C99:
          msg_intercept(char * msg, char * del , int nb, char *tab[nb])
          Mais c'est une fonctionnalité (les tableaux de taille variable, ou VLA) qui est "broken" dans gcc...


          sizeof (tab ) = 16 dans main() car c'est un tableau de 4 pointeurs
          Non: sizeof tab == 4 * sizeof(*char). Il y a des architectures où les deux coïncident, mais c'est loin d'être universel...

          sizeof (tab) =4 dans msg_intercept car c'est un pointeur.
          Idem: sizeof tab == sizeof(**char)
  • # structure

    Posté par  . Évalué à 1.

    si tu tiens vraiment à renvoyer un tableau, tu peux renvoyer une structure contenant un seul champ: le tableau


    struct str { char p[4];};
    ...
    struct str fonction(...){
    struct str res;
    ...
    return res;
    }



    mais la variable de retour sera de type struct str et non pas str et sera accessible par resultat.p[i]

    c'est un peu tordu car le C ne renvoie pas de tableau.
    (bien sûr, j'ai considéré que tu ne voulais pas toucher aux données sur lesquelles on applique le traitement et d'ailleurs il serait préférable de les "conster")

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.