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

Langage C++ Discussion :

Votre avis sur ma fonction : cpp_sscanf (plus rapide que sscanf)


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Par défaut Votre avis sur ma fonction : cpp_sscanf (plus rapide que sscanf)
    Bonjour à tous,
    La fonction sscanf du C n'étant pas sécurisée, et donc presque inutilisable, j'ai décidé de coder un équivalent [extensible] en c++11 moderne.


    Prototypes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (1)
    template <class... Outs>
    string::const_iterator cpp_sscanf::sscanf( string input, string pattern, char delimiter, Outs&... output_arguments );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (2)
    template <class Iterator, class... Outs>
    Iterator cpp_sscanf::sscanf( Iterator begin, Iterator end, string pattern, char delimiter, Outs&... output_arguments );

    Fonctionnalités.

    - La fonction sscanf parse une chaine (input) de caractère selon un format fourni (pattern) et en extrait des valeurs (output_arguments).
    - Elle retourne un itérateur vers la position où le parsing s'est arrêté.
    - Les types pris en charge pour la sortie sont extensibles, via des type_traits.
    - Grâce au c++, cette version est plus rapide que celle du C.
    - Plus rapide que les std::istream (qui sont abominablement lents), et surtout, plus lisible.
    - Bonne gestion des erreurs grâce aux exceptions.
    - Testée.

    Mini exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cpp_sscanf::sscanf( "j'ai 10 ans"  ,  "j'ai _ ans"  ,  '_'  ,  mon_age );

    Exemple.

    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
     
        #include "cpp_sscanf.h"
        #include "parser_trait.h"
        #include <string>
        using namespace std;
     
        int main(){
            string chaine_a_tester = ...;
            string pattern = "Julien : _ ans, Diane : _ ans";
            double age_julien; double age_diane;
     
            cpp_sscanf::sscanf( chaine_a_tester , pattern , '_' , age_julien, age_diane );
     
            cout << "l'age de Julien est : " << age_julien << endl;
            cout << "l'age de Diane est : " << age_diane << endl;
        }
    Sources.

    Les sources, les tests et le readme sont là :
    https://bitbucket.org/Gauss_/library...anf/?at=master

    Votre avis.

    Qu'en pensez-vous ? Peut-on améliorer le code ? Cela vous semble-t-il utile ?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Salut,

    ça a l'air sympa, mais ça ne permet que de scanner 1 variable dans une chaîne ?
    Personnellement je n'y vois pas d'intérêt par rapport à l'utilisation d'une regexp, que je connais et est plus "paramétrable"/"utilisable".
    En tous cas le code est plutôt agréable à lire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre averti
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Par défaut
    Bonjour,
    Pas qu'une seule variable heureusement !

    Cette fonction permet de lire autant de variables que nécessaire dans la string (input) fournie, tout en vérifiant que le format est valide, selon le modèle défini par le pattern.

    Les regex sont en effet le candidat de choix en c++ . Personnellement, je les trouve assez fastidieuses à utiliser, et moins lisibles qu'un appel à sscanf. Voici un exemple :

    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
     
    // Avec Regex :
    //
    string input = ...;
    string decimal = R"(-?\d*\.?\d+(?:e[+-]?\d+)?)";
    string entier = R"(-?\d+)";
     
    regex pattern{ "commande : " +entier+ " paquets de " +decimal+ "g\n" };
     
    smatch sm;
    regex_match(input,sm,pattern);
     
    if(sm.size() != ...){
       //erreur de parsing
    }
     
    int quantite;
    double grammes;
    //recupérer les valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // Avec sscanf :
    //
    string input = ...;
    string pattern = "commande : _ paquets de _g\n";
    int quantite; 
    double grammes;
     
    try{
       sscanf(input, pattern, quantite, grammes);
    }
    catch(CouldNotParseArgument& e){
       //...
    }
    Note :
    J'ai édité les prototypes de mon premier message pour rajouter la ligne (que j'avais omise):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class... Outs>

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Pourquoi tu fais des regexp aussi compliquées aussi ? regex_match(input, sm, regex("commande: (.*?) paquets de (.*?)g)); est largement suffisant et correspond à ton scanf.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre averti
    Homme Profil pro
    C++
    Inscrit en
    Janvier 2013
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : C++

    Informations forums :
    Inscription : Janvier 2013
    Messages : 45
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Pourquoi tu fais des regexp aussi compliquées aussi ? regex_match(input, sm, regex("commande: (.*?) paquets de (.*?)g)); est largement suffisant et correspond à ton scanf.
    Ah je ne suis pas un expert avec les regex...
    Mais comment ensuite vérifier que l'entrée n'est pas invalide du type : input = "commande: 52abc paquets de 10.4g" ?
    (Par exemple dans un test unitaire pour le format de sortie)

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    regex_match(input, sm, regex("commande: ([0-9]*) paquets de ([0-9]*)g));
    permet de vérifier que tu n'entres que des nombres. Pour plus d'infos sur les regex : http://regexone.com/ par exemple

Discussions similaires

  1. Réponses: 9
    Dernier message: 02/09/2008, 13h52
  2. Donnez votre avis sur les articles de Developpez.com
    Par Geronimo dans le forum C++Builder
    Réponses: 13
    Dernier message: 14/01/2007, 22h00
  3. Donnez votre avis sur les articles de Developpez
    Par Anomaly dans le forum Contribuez
    Réponses: 37
    Dernier message: 29/05/2006, 21h48
  4. [Débat] Votre avis sur la section "Dev Web"
    Par Marc Lussac dans le forum Evolutions du club
    Réponses: 31
    Dernier message: 03/03/2004, 20h55
  5. Votre avis sur 1 livre SVP
    Par cab dans le forum DirectX
    Réponses: 4
    Dernier message: 17/09/2003, 10h39

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