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

Boost C++ Discussion :

utilisation de boost::locale et conversion text -> nombre


Sujet :

Boost C++

  1. #1
    Membre régulier Avatar de corwin
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2002
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 85
    Points : 77
    Points
    77
    Par défaut utilisation de boost::locale et conversion text -> nombre
    Bonjour,
    quelqu'un pourrait il m'éclairer sur l'usage de boost:locale. Je souhaiterais convertir des chaines de texte suivant différentes locales : typiquement FR et US.
    voici un bout de code qui ne marche pas et qui lève une exception.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        string  spi = "3,14";
        BOOST_LOG_TRIVIAL(debug) << "try to convert " << spi;
        std::locale loc= boost::locale::generator().generate("fr_FR.UTF-8");
        std::locale oldloc = std::locale::global(loc);
        BOOST_LOG_TRIVIAL(debug) << "change locale from : "<< oldloc.name().c_str() << " to : "<<loc.name().c_str();
        char point = std::use_facet< std::numpunct<char> >(std::cin.getloc()).decimal_point();
        std::locale l1;
        BOOST_LOG_TRIVIAL(debug) << "locale l1 = "<<l1.name().c_str()<<" decimal sep = "<<point;
        try{
            double pi = boost::lexical_cast<double>(spi);
            BOOST_LOG_TRIVIAL(debug) << "pi=" << pi;
        }catch(boost::bad_lexical_cast & e){
            BOOST_LOG_TRIVIAL(debug) << "lexical cast error : " << e.what();
        }
    Cela me donne à l'éxécution la sortie suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [2020-05-06 07:50:20.628677] [0x00007fccc8355740] [debug]   try to convert 3,14
    [2020-05-06 07:50:20.630141] [0x00007fccc8355740] [debug]   change locale from : C to : *
    [2020-05-06 07:50:20.630214] [0x00007fccc8355740] [debug]   locale l1 = * decimal sep = .
    [2020-05-06 07:50:20.630522] [0x00007fccc8355740] [debug]   lexical cast error : bad lexical cast: source type value could not be interpreted as target
    Je ne comprend pas comment réaliser mes conversions de chaine de texte contenant des nombres selon différentes locales.

    merci d'avance de vos idées/explications.

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 7 084
    Points : 32 766
    Points
    32 766
    Billets dans le blog
    4
    Par défaut
    L'erreur n'est pas juste qu'il cherche un . comme séparateur décimal alors que ta chaîne a une , ?
    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 régulier Avatar de corwin
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2002
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 85
    Points : 77
    Points
    77
    Par défaut
    oui l'erreur que j'ai c'est ca mais.. je voudrais convertir des nombres à virgule «,» et du coup je ne sais pas comment faire. Je pensais que en utilisant la locales FR cela marcherait.
    L'autre truc bizarre c'est que même si j'ai setter la local a FR quand je lui demande de l afficher : l1.name.c_str() il affiche '*' : j em attendais a un affichage contenant « FR ».
    Du coup j'ai aucune piste : la doc de bosst.locale est très sommaire et je n'ai rien trouver dans les forums.

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 531
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 531
    Points : 7 490
    Points
    7 490
    Par défaut
    Bonjour,
    je ne connais pas bien boost. Avec les objets de la bibliothèque de base ça marche très bien.
    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
    	std::string pi_fr_str = "3,14";
    	std::stringstream ss{ pi_fr_str };
    	ss.imbue( std::locale( "fr_FR.UTF-8" ) );
    	double y;
    	ss >> y;  // conversion de "3,14" français vers nombre
    	std::cout << "chaine/fr : " << pi_fr_str << " => le nombre : " << y << std::endl;
     
    	ss = std::stringstream{};
    	ss.imbue( std::locale( "en_US.UTF-8" ) );
    	ss << y;  // conversion anglaise de PI
    	std::string str_en = ss.str();
     
    	ss = std::stringstream{};
    	ss.imbue( std::locale( "fr_FR.UTF-8" ) );
    	ss << y; // conversion française de PI
    	std::string str_fr = ss.str();
     
    	std::cout << "nombre : " << y << " => str/en : "  << str_en << " => str/fr : " << str_fr << std::endl;

  5. #5
    Membre régulier Avatar de corwin
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2002
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 85
    Points : 77
    Points
    77
    Par défaut
    Bonjour dalfab,

    j'ai testé ton code : du coup je récupère une erreur : std::runtime_error: locale::facet::_S_create_c_locale name not valid

    celle ci est résolue une fois que l on génère la locale us_US.

    Mon problème est momentanément résolu : je suis sous linux et j'ai pu générer la locale.

    Maintenant , ce petit bout de code doit s insérer dans une librairie qui peut etre executer sur différent système d exploitation d'ou mon usage de boost au départ. Du coup je ne suis pas sur que ceal va être très portable.

    Ma question : as tu utilisé ce code sous Mac ou Windows et comment gérer les locales sous ses systèmes ?

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 531
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 531
    Points : 7 490
    Points
    7 490
    Par défaut
    Bonjour,

    Mon code s'est déroulé avec MSVC donc sous Windows (donc pas avec gcc). Il faudrait voir s'il marche avec MinGW sous Windows.
    Le problème est que les noms des locales sont libres et dépendraient à la fois du compilateur et du système d'exploitation.
    Et je ne comprend pas le concept de générer une locale. Une locale a un nom, la génération ça doit venir de boost je pense. Dans le cas présent j'aurais pu utiliser std::locale("fr_FR") car le ".UTF-8" ne sert qu'à préciser comment les wchar_t seront convertis en char et cette facet<> n'intervient pas dans ton exemple qui n'est qu'un problème de régionalisation.

  7. #7
    Membre régulier Avatar de corwin
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2002
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 85
    Points : 77
    Points
    77
    Par défaut
    Sous linux les locales sont installées à l installation du système. Tu peux choisir. mon système par defaut a fr_FR et en_EN mais n'avait pas en_US. Du coup j'avais une erreur. J'ai donc relancer le système de configuration pour qu il génère et installe les fichiers systèmes complémentaires. A oui la génération se base sur la convention de nommage posix : fr_FR-XYZ

    De ce que j'ai compris pour boost (pas sur que cela soit exact) :
    c'est qu'il utilise une grosse lib ( Localization library: ICU - International Components for Unicode. ) qui permet à l’exécution de générer un objet local en mémoire et non pas d'aller chercher ce qu il faut dans le système. Ce qui a priori rend le code complètement indépendant de l environnement ou il tourne.

    Voilà mais je n'arrive pas a utiliser cette partie de boost.

    Extrait de la doc boost :

    The class generator provides tools to generate the locales we need. The simplest way to use generator is to create a locale and set it as the global one:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <boost/locale.hpp>
    using namespace boost::locale;
    int main()
    {
        generator gen;
        // Create locale generator 
        std::locale::global(gen("")); 
        // "" - the system default locale, set
        // it globally
    }
    Of course we can also specify the locale manually
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::locale loc = gen("en_US.UTF-8"); 
    // Use English, United States locale

Discussions similaires

  1. [XL-2010] Conversion texte en nombre plus format
    Par halaster08 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 10/05/2018, 07h51
  2. [XL-2003] Conversion texte vers nombre
    Par Toine-45 dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 10/01/2014, 17h40
  3. [PROC] Conversion texte en nombre
    Par pierreTPE57 dans le forum SAS Base
    Réponses: 3
    Dernier message: 09/11/2012, 14h29
  4. Conversion texte en nombre
    Par berapard dans le forum Langage SQL
    Réponses: 3
    Dernier message: 02/07/2008, 12h29
  5. utilisation de set locale
    Par ColonelHati dans le forum C
    Réponses: 7
    Dernier message: 02/05/2005, 14h25

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