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 :

Parser une chaine


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Par défaut Parser une chaine
    Bonjour,

    j'ai une chaine type :

    nom-(val1,val2,val3)-[AAAA-MM-JJ-HH-MM-SS].extension

    Je voudrais parser ce type de chaine en récupérant les valeurs, la dateheure et le nom du document.

    J'ai une structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct ParseFile {
    	char * fileName;
    	char * fileNameOnly;
    	char * listOfVal[256];
    	char * fileDate;
    };
    Le but est de remplir cette structure avec :
    filename = "nom-(val1,val2,val3)-[AAAA-MM-JJ-HH-MM-SS].extension"
    fileNameOnly = "nom.extension"
    listOfVal = [val1,val2,val3]
    filedate = "AAAA-MM-JJ-HH-MM-SS"

    Je connais la méthode strtok qui permet de parser une chaine. Le problème est qu'elle marche avec une liste de caractère comme délimiteur c'est à dire "-" et/ou "(" et/ou ... mais je ne peux pas lui donner une chaine comme délimiteur comme "-(" ou "-[".

    Du coup je me dis qu'il faut parcourir ma chaine caractère par caractère en gardant en mémoire le caractère précédemment lu et si le caractère courant est égal à "(" ou "[" et que le précédent est égal à "-" alors je coupe.

    Avez vous d'autres idées afin de parser au mieux ce type de chaine.

    Merci par avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Hum les regex. C'est p'tet un peu lourdingue pour ce que tu veux faire ^^ Mais y'en a une implémentation dans la GLib.

    Enfin ton idée n'est pas mauvaise non plus (à la réserve qu'elle soit bien codée :p).

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    sscanf est ce qu'il te faut. Et en plus, tu as un super tuto dessus sur http://c.developpez.com/cours
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #4
    Membre confirmé
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    Je vais essayer de regarder du côté des expressions régulières et comprendre le concept.
    Mais le fait que j'ai des '[' et ']' dans le nom ne va t'il pas poser problème ?

    En ce qui concerne le sscanf, sauf erreur de ma part, je vois deux problèmes :
    - les chaines en argument doivent être allouées mais je ne connais pas la taille des chaines à l'avance,
    - il est possible que les parties -(val1, ... valN)- et -[date] n'existent pas dans ma chaine.

    Des exemples de chaines possibles :
    - toto.txt
    - toto-(éti1, éti2, éti 3 p o).txt
    - toto-[2010-12-31].txt
    - toto-[2010-12-31-22-59-33].txt
    - toto-(éti1, éti2, éti 3 p o)-[2010-12-31].txt
    - toto-(éti1, éti2, éti 3 p o)-[2010-12-31-22].txt
    - toto-(éti1, éti2, éti 3 p o)-[2010-12-31-22-].txt
    - toto-(éti1, éti2, éti 3 p o)-[2010-12-31-22-59-33].txt

    Mon code de test a été :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char * extension;
    char * name;
    char * listOfVal;
    char * date;
    sscanf("toto-(éti1, éti2, éti 3 p o)-[2010-12-31-22-59-33].txt", "%s-(%s)-[%s].%s",name, listOfVal, date, extension);

  5. #5
    Membre Expert
    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
    Par défaut
    Il y a aussi la méthode de l'analyse "manuelle", un peu plus périlleuse mais qui est -je trouve- un peu plus formatrice.

    Moi, voici ce que je ferais, dans l'ordre :

    Je recherche d'abord la position d'un -(. Si elle existe, je cherche aussi celle du ), à partir de la position -( trouvée. J'analyse (ou récupère pour mettre dans listofval) tout ce qu'il y a dedans, sachant que la virgule est un séparateur. Je récupère le nom entre la position 0 et la position -( moins 1. Je me place après ).

    Même chose pour la recherche -[ et ]. Si je trouve, j'analyse (ou récupère pour mettre dans filedate) si le format est bien respecté et éventuellement que la date est valide. Si le nom n'a pas été récupéré, je le récupère entre la position 0 et la position -[ moins 1. Je me place après ].

    Si aucun -( ni -[ n'a été trouvé, la chaine à parser correspond au nom, je copie dans fileNameOnly. Sinon, je copie le nom précédemment trouvé dans fileNameOnly, puis je concatène avec le reste de la chaine à parser (à partir de la position courante).

    Si la taille de la chaine à parser varie, il suffit de créer un tableau suffisamment grand, d'une valeur arbitraire (au pif, 128 ou 256).

    Pour rechercher une sous-chaine dans une chaine : fonction strstr.
    Pour rechercher un caractère dans une chaine : fonction strchr.
    Pour concaténer une chaine : fonction strcat.
    Pour copier une chaine : fonction strcpy (strncpy de préférence).

  6. #6
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Il y a aussi la méthode de l'analyse "manuelle", un peu plus périlleuse mais qui est -je trouve- un peu plus formatrice.
    Oui, mais elle est souvent beaucoup moins performante que les fonctions deja implementees.

    En ce qui concerne le sscanf, sauf erreur de ma part, je vois deux problèmes :
    - les chaines en argument doivent être allouées mais je ne connais pas la taille des chaines à l'avance,
    - il est possible que les parties -(val1, ... valN)- et -[date] n'existent pas dans ma chaine.
    Le probleme des chaines allouees, tu l'auras forcement.
    Pour ce qui est des parties inexistantes, ca depend si c'est en fin de chaine ou non : si c'est en fin de chaine, pas de soucis (sscanf te retournera le nombre de token bien lus). Sinon, je pense que tu n'as pas d'autres choix que les regexp, mais je ne suis pas certain que ce soit simple.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  7. #7
    Expert confirmé

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Sango64 Voir le message
    Je connais la méthode strtok qui permet de parser une chaine. Le problème est qu'elle marche avec une liste de caractère comme délimiteur c'est à dire "-" et/ou "(" et/ou ... mais je ne peux pas lui donner une chaine comme délimiteur comme "-(" ou "-[".
    presque, si..

    Il suffit d'utiliser la fonction strstr...

Discussions similaires

  1. Parser une chaine de caractère
    Par Nasky dans le forum C++
    Réponses: 7
    Dernier message: 04/12/2006, 19h37
  2. Parser une chaine de doubles
    Par Ange44 dans le forum C++
    Réponses: 9
    Dernier message: 28/06/2006, 13h12
  3. Réponses: 9
    Dernier message: 30/11/2005, 18h18
  4. Parser une chaine
    Par TieumB dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 17/01/2005, 11h20
  5. Parser une chaine en shell script
    Par Gogoye dans le forum Linux
    Réponses: 10
    Dernier message: 19/07/2004, 17h49

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