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 et "champs" vides


Sujet :

C

  1. #1
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut strtok et "champs" vides
    Bonjour,
    Je dois découper une chaîne de caractères selon un caractère de séparation, pour cela j'utilise strtok. Tout fonctionne tant que les valeurs entre les séparateurs sont bien renseignées. Mais j'ai des cas où certaines valeurs manquent, et les séparateurs sont alors collés.
    Exemple
    Le problème c'est que j'ai l'impression que strtok va alors lire la valeur suivant les séparateurs collés, et donc "sauter" la valeur absente. Ce qui du coup me décale tout car je me base sur l'ordre d'apparition des valeurs pour déterminer leur rôle.

    Est-ce que vous auriez une idée pour être informé quand même lorsqu'il y a un vide entre 2 séparateurs ?
    Merci d'avance.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    C'est effectivement une limitation de strtok()

    essaye avec strsep() si il existe dans ta libc

    La fonction strsep() a été introduite en remplacement de strtok(), qui ne peut pas traiter les champs vides. Néanmoins strtok() est conforme au C ANSI et est donc plus portable.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Je n'ai pas d'erreur d'include pour <string.h>, par contre j'ai une erreur de link avec le symbole "strsep", bizarre :/

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Je n'ai pas d'erreur d'include pour <string.h>
    Bien sûr. Il s'agit d'un fichier standard donc présent quel que soit le compilateur que tu utilises. Tu voulais dire peut-être que t'as pas d'erreur de compilation mais seulement d'édition des liens ? Normal, la déclaration d'une fonction n'est pas obligatoire en C. Seulement, lorsqu'une fonction n'est pas déclarée, le compilateur suppose qu'il s'agit d'une fonction qui retourne un int. Si la fonction existe dans un des fichiers sources de tes projets mais ne retourne pas un int, le compilateur génèrera une erreur ("déclaration != définition"). Sinon, la fonction sera cherchée pendant l'édition des liens et si elle n'est pas trouvée, l'éditeur des liens génèrera une erreur.
    par contre j'ai une erreur de link avec le symbole "strsep"
    C'est que cette fonction n'est pas disponible dans l'implémentation que tu utilises ou que tu ne t'es pas lié avec le fichier objet qui la contient, mais c'est plus que certain qu'on est dans le premier cas. Mon intuition me le dit .

    Si le format est le même pour chaque ligne (nb1;nb2;nb3;nb4), utilise sscanf. Par exemple (première approximation) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    n = sscanf(ligne, "%[0-9];%[0-9];%[0-9];%[0-9]", s1, s2, s3, s4);
    Où s1, s2, s3, s4 sont des tableaux de char (char s1[51], etc.). Si tout se passe bien, n devra contenir 4 : le nombre de lectures formatées réussies. Utilise ensuite atoi ou strtol pour convertir les chaînes lues en entier. Ici, atoi est plus que suffisant.

    Dans le code précédent, la taille des buffers s1, s2, s3, s4 n'est pas renseignée à sscanf => risque de débordement de tampon. Le bon code est donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    n = sscanf(ligne, "%50[0-9];%50[0-9];%50[0-9];%50[0-9]", s1, s2, s3, s4);
    Enfin, la véritable bonne solution c'est de se fabriquer un tokenizer adapté à ses besoins ou d'utiliser des fonctions libres de droit en cherchant un peu sur le net.

  5. #5
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Merci de ta réponse, l'inconvénient de ta solution est de fixer le nombre de valeurs par ligne, j'aurais préféré garder quelque chose plus flexible (actuellement je boucle avec strtok). Je sens que je vais devoir traiter la chaîne "à la main" donc.

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    C'est souvent plus pratique de boucler avec strchr, en détruisant la chaîne au passage (remplacement du token par un zéro) et en remplissant au passage un tableau de char* passé en paramètre. C'est portable, rapide, et ça gère les champs vides et/ou composites...

    De plus, même si ce n'est plus (trop) un problème avec les compilateurs récents, il faut savoir que strtok n'était habituellement pas compatible avec le multithreading, car elle n'était pas réentrante... Ce qui n'est pas le cas d'une boucle avec strchr.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Merci ! Mais entre temps j'ai fait mon propre truc caractère par caractère. Ca servira peut être à quelqu'un qui cherchera la même chose que moi.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    De plus, même si ce n'est plus (trop) un problème avec les compilateurs récents, il faut savoir que strtok n'était habituellement pas compatible avec le multithreading, car elle n'était pas réentrante... Ce qui n'est pas le cas d'une boucle avec strchr.
    "Habituellement" étant un mot-clé ici. La version Microsoft, bien que toujours pas réentrante, restait compatible avec le multithreading, parce qu'elle utilisait du Thread-Local Storage...
    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.

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    "Habituellement" étant un mot-clé ici. La version Microsoft, bien que toujours pas réentrante, restait compatible avec le multithreading, parce qu'elle utilisait du Thread-Local Storage...
    Tout à fait. C'était juste pour souligner que, comme d'autres fonctions de la CLib, strtok est une fonction potentiellement "dangereuse" à utiliser... C'est comme "scanf", autre fonction difficile à bien utiliser (= sans risquer les gros bugs à l'exécution) : vaut mieux savoir qu'il y a des risques (et ne pas être surpris) que de croire aveuglément que la fonction est fiable, et devenir fou à chercher une erreur qui n'en est pas une...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

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

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