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 :

sscanf et la lecture de données entre guillemets


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 91
    Par défaut sscanf et la lecture de données entre guillemets
    Bonjour.

    J'ai une question toute bete et j'arrive pas a trouver le reponse depuis ce matin...

    J'ai une chaine de caracteres comme celle ci :
    "Nicolas Eymerich,Inquisiteur" "La deesse" 1 "zentner" "sala" "delcourt" "pas lus" "_" "_"


    J'aimerais avec un sscanf du genre :
    sscanf(lLigne,MASQUE,lSerie,lTitle,&lTome,lDessinateur,lScenariste,lEditeur,lComment,lPicture,lPret);

    pouvoir recuperer les données entre guillemets et je n'arrive pas a trouver le masque adequat....

    l'auriez vous sous la main?

    Merci d'avance

  2. #2
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Les pros du scanf ne seront pas sur ce forum.
    J'aurais tendance à partir sur les regex (-> boost.regex), ou a utiliser des tabulations plutôt que des guillemets pour séparer les divers champs de ta BD de BDs.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pour l'utilisation de sscanf il faut mieux voir sur le forum C.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 91
    Par défaut
    Merci a tous les deux. Je vais aller poser ma uestion sur le forum du C.

    Désolé pour le derangement

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par loufoque
    Pour l'utilisation de sscanf il faut mieux voir sur le forum C.
    Bof cette fonction est tellement compliquée qu'elle est rarement utilisée en C.

    Donc si en C++ vous avez autre chose (ce n'est pas possible pas les stream ?) autant en profiter.

    Scanf démythifiée

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Vous pouvez essayer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int res = sscanf( ligne, "`\"%s\"\"%s\"\"%d\"\"%f\"", chaine1, chaine2, &unentier, &unfloat) ;
    res renvoit le nombre de conversions réalisées.

    Je ne garantis pas le résultat.

    Mieux vaut se servir des flux ( sstream ) ou d' un string::tokenizer

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Si tu veux travailler en C++, il sera beaucoup plus facile d'utiliser les outils fournis par C++...

    Je penses, entre autres, aux string et aux istringstream fournis dans la bibliotheque stantdard.

    L'une des possiblités pourraient etre la suivante:
    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
     
    /* fonction qui prend la chaine de caractères et renvoye un tableau
       contenant les différents champs
       @in chaine "brute"
       @out tableau traité
       @require <vector>, <string>, <sstream>
     */
    std::vector<std::string> TraiteChaine(const std::string& chaine)
    {
        // on utilise un istringstream pour gérer les choses
        std::istringstream iss(chaine);
        //il nous faut une chainte temporaire
        std::string mot;
        // et un tableau pour le résultat
        std::vector<std::string> resultat;
        // on va travailler tant que l'istringstream n'a pas été entièrement traité
        // en découpant le flux à chaque "
        while(std::cin(iss,mot,'\"'))
        {
            //Au premier passage, mot vaut "", et, comme on a des " " qui
            //séparent parfois deux chaines, on les supprime
            if(mot!="" && mot!=" ")
            {
                //Dans certains cas, il y a des espaces surnuméraires avant
                // et/ou apres, supprimons les
                mot=mot.substr(mot.find_first_not_of(" "),mot.find_last_not_of(" ")+1);
                //juste pour te montrer le fonctionnement
                std::cout<<mot<<std::endl;
                //et placement du résultat dans le tableau
                resultat.push_back(mot);
            }
        }
        //fini :D on renvoie le tableau créé
        return resultat;
    }
    Ceci dit, il faut se rendre compte de plusieurs choses:

    • Certains champs sont, définitivement, numériques
    • L'utilisation des caractères " pour délimiter les chaines n'est pas ce qui se fait de mieux (l'utilisation d'un caractere "non utilisé" (tabulation, "pipe", ...)pourrait faciliter les choses)

    Il serait donc pas mal d'envisager:
    La création d'une structure pour les différents champs, adaptés à ce qu'ils doivent contenir
    de modifier la chaine pour ne pas forcément avoir les guillemets (hormis ceux qui doivent apparaitre dans une chaine)

    La structure que je verrais bien est du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    struct livre
    {
        std::string titre;
        std::string heros; //collection, peut etre ??
        int tome; //je présumes que le 1, c'est pour "tome 1"???
        std::string senario; //voir qui a fait quoi dans le groupe ;)
        std::string dessin; //
        std::string coauteur;
        //manquent les deux "-" pour lesquels ils faudrait savoir ce qu'ils 
        //représentent :P
        bool lu; //dans le fichier, prendrait "0" si non lu, 1 si lu...
    };
    La chaine deviendrait alors du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Nicolas Eymerich,Inquisiteur\tLa deesse\t1\tzentner\tsala\tdelcourt\t0\t_\t_\n
    (les \t représentant des tabulations, tu t'en doutes peut etre )

    La fonction de récupération de la chaine pourrait devenir
    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
     
    /* fonction qui utilise les modifications proposées
       @in référence sur la structure adequate
           chaine à traiter
     */
    void TraiteChaine(const std::string& chaine, livre& enreg)
    {
        // il nous faut toujours le flux istringstream
        std::istringstream iss(chaine);
        //il nous faudra parfois éviter un \t ou l'autre...
        char ignore;
        // les différentes chaines risquent d'avoir des espaces,  
        // on s'arrete donc au \t suivant
        std::getline(iss,recup.titre,'\t');
        std::getline(iss,recup.heros,'\t');
        iss>>recup.tome>>ignore;
        std::getline(iss,recup.senario,'\t');
        std::getline(iss,recup.dessin,'\t');
        std::getline(iss,recup.coauteur,'\t');
        iss>>recup.lu>>ignore;
        std::getline(iss,recup.chaine1,'\t');
        std::getline(iss,recup.chaine2,'\t');
    }
    et, l'affichage qui va bien avec la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        std::cout<<recup.titre<<std::endl
                 <<recup.heros<<std::endl
                 <<recup.tome<<std::endl
                 <<recup.senario<<std::endl
                 <<recup.dessin<<std::endl
                 <<recup.coauteur<<std::endl
                 <<recup.chaine1<<std::endl
                 <<recup.chaine2<<std::endl
                 <<( (recup.lu) ? "lu": "non lu")<<std::endl;
    que tu peux, bien évidemment, agrémenter à ta guise
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. [XL-2003] Lecture de données entrées dans une feuille par une macro
    Par martinmacfly dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 16/12/2009, 16h29
  2. Récuperation de données entre guillemets
    Par Joccy dans le forum Langage
    Réponses: 8
    Dernier message: 13/11/2007, 16h36
  3. Comment récuperer des données entrées au clavier?
    Par Elisée A. dans le forum MFC
    Réponses: 2
    Dernier message: 13/02/2004, 07h22
  4. lecture de données a partir de fichier
    Par sana dans le forum MFC
    Réponses: 5
    Dernier message: 21/01/2004, 12h57
  5. [Kylix] Echange de données entre fiches
    Par _dack_ dans le forum EDI
    Réponses: 1
    Dernier message: 01/07/2003, 11h34

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