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 :

[strtok_r] Voir le prochain caractère


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Points : 93
    Points
    93
    Par défaut [strtok_r] Voir le prochain caractère
    Je parse une chaine avec strtok_r.

    Admettons que mon caractère de séparation soit ";".

    Si je fais un stork_r sur la chaine "chaine;", je récupère au premier appel "chaine".
    Mais si je fais ";chaine" , je récupère aussi "chaine".

    J'aimerais ne rien récupérer si ma chaine commence par le caractère délimiteur.

    Merci.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Ben il suffit tout simplement de tester le premier caractère, non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (chaine_a_parser[0] != ';')
    {
      jeparse();
    } else
    {
      jeparsepas();
    }

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Points : 93
    Points
    93
    Par défaut
    Ok, mais je parcours ma chaine avec strtok_r.

    Par exemple, ma chaine : "abc.def;ghi"

    Je commence avec un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strtok_r(maChaine, ".", &position);
    Pour avoir la chaine avant le point.

    Et je continue avec un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strtok_r(NULL, ";", &position);
    Pour avoir la chaine avant le point virgule.

    Mais si ma chaine ressemble à ça : "abc.;ghi"
    Et que je fais les deux même strtok_r, j'aurai "abc" puis "ghi".
    Et ce que j'aimerais, c'est récupérer "abc" puis NULL.
    En d'autre terme détecter que j'ai une chaine vide avant le point virgule.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    D'après le man :
    Si un token se termine par un délimiteur, le caractère de délimitation est surchargé par un \0 et un pointeur sur le caractère suivant est mémorisé pour l'appel suivant à strtok().
    Cela veut dire que si deux délimiteurs se suivent, la position suivante se fera sur le second délimiteur. Si on veut parser ou non le reste, il suffit donc de tester si le caractère est différent du point-virgule.

    On résume.
    Si ta chaine a un format(avec "token1" et "token3" toujours présents, i.e. pas de vérification à faire)

    1) Tu appelles strtok_r une première fois, en utilisant le délimiteur "point". La fonction te retournera un pointeur pointant sur le premier token.
    2) Ensuite, tu testes le caractère situé à l'adresse position. Si c'est le point-virgule, cela veut dire qu'il n'y a aucun token entre les deux délimiteurs (i.e. les deux délimiteurs se suivent). Donc, tu stoppes le parsing (si j'ai bien compris ce que tu veux faire). Si ce n'est pas un point-virgule, tu appelles strtok_r une seconde fois avec le délimiteur "point-virgule". La fonction te retournera un pointeur pointant vers le second token.
    3) Pour finir, position pointera sur le troisième token.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Points : 93
    Points
    93
    Par défaut
    Citation Envoyé par jeroman Voir le message
    2) Ensuite, tu testes le caractère situé à l'adresse position.
    Ok mais je ne vois pas trop comment faire ça.

    Car à un instant t dans strtok_r "position" contient la partie restante de la chaine mais sans le caractère délimiteur.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Ok mais je ne vois pas trop comment faire ça. Car à un instant t dans strtok_r "position" contient la partie restante de la chaine mais sans le caractère délimiteur.
    Oui, suite au premier appel de strtok_r, position pointe sur la partie à analyser lors d'un prochain appel. Si à cette adresse se trouve un délimiteur, cela veut dire que deux délimiteurs se suivent.

    Voilà le principe. A adapter/optimiser.
    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
    	char maChaine[] = "abc.def;ghi"; /* essayer aussi avec : "abc.;ghi" */
    	char * position;
    	char *token1;
    	char *token2;
    	char *token3;
     
    	token1 = strtok_r(maChaine,".",&position); /* token1 pointe vers le 1er token */
    	if (*position != ';') /* on s'assure que deux délimiteurs ne se suivent pas */
    	{
    	   token2 = strtok_r(NULL,";",&position);  /* token2 pointe vers le 2eme token */
    	   token3 = position; /*token3 pointe vers le 3eme token */
     
    	   printf("*%s*\n",token1);
    	   printf("*%s*\n",token2);
    	   printf("*%s*\n",token3);
    	} else
    		printf("erreur token2\n");
    Je précise bien que la vérification se fait uniquement sur le second token, en accord avec les précisions dans ton message plus haut. S'il faut également vérifier les autres, il faudra modifier le code en conséquence.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    273
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Août 2009
    Messages : 273
    Points : 93
    Points
    93
    Par défaut
    Mon soucis n'est pas de voir si deux délimiteurs se suivent.
    C'est plutôt de voir si la chaine que je suis entrain d'analyser commence par un caractère.

    Ce que j'aimerais différencier au cours du parse c'est de

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Je ne comprends pas ce que tu ne comprends pas.

    Soyons logiques. Si ta chaine commence par un délimiteur, c'est que le premier token n'est pas dans la chaine, sinon elle ne commencerait pas par un délimiteur. De la même manière, si deux délimiteurs se suivent, c'est qu'il n'y a pas de token entre les deux, sinon ils ne se suivraient pas. CQFD
    Dans les deux cas, il y a juste à effectuer un test : pour vérifier la présence du premier token, il n'y a qu'à tester le premier caractère de la chaine, et après chaque appel à strtok_r, pour vérifier la présence des tokens suivants, il suffit de tester le caractère pointé par le pointeur, celui dont son adresse est donné comme 3eme argument de la fonction (dans ton exemple, il s'agit du pointeur position).

    Hélas, avec strtok(_r) seul, tu ne pourras pas effectuer ce genre de test, car avec cette fonction, si à la position courante se trouve un délimiteur, ce délimiteur et ceux qui suivent (s'il y en a) seront zappés, jusqu'à ce qu'un caractère autre que délimiteur soit trouvé.
    Par exemple, ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	char maChaine[] = "........abc....def";
    	char * position_suivante;
    	char * token1;
    	char * token2;
     
    	token1 = strtok_r(maChaine , "." , &position_suivante);
    	printf("%s\n",token1);
    	token2 = strtok_r(NULL , "." , &position_suivante);
    	printf("%s\n",token2);
    affichera "abc" et "def" : tous les délimiteurs précédant un token à trouver seront zappés.
    La fonction ne fait "que" trouver un token (elle renverra l'adresse de celui-ci), après avoir zappé les délimiteurs éventuels situés avant, puis elle remplace le premier délimiteur (situé après ce token) par un '\0', puis assigne au troisième pointeur l'adresse située après ce '\0'. Et ce, à chaque appel.
    Donc, pour tester la présence d'un ou de plusieurs délimiteurs éventuellement présents à l'avant d'un token, il faut le faire soi-même, la fonction strtok(_r) ne peut rien faire pour nous.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/04/2018, 01h29
  2. Réponses: 33
    Dernier message: 15/07/2015, 08h30
  3. [Débutant] Trouver un string et écrire les prochains caractères
    Par YaMOo dans le forum Windows Forms
    Réponses: 2
    Dernier message: 07/07/2014, 19h33
  4. Réponses: 6
    Dernier message: 15/07/2013, 16h44

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