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 :

Ma conversion string en double tronque..


Sujet :

C++

  1. #1
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut Ma conversion string en double tronque..
    Bonjour,

    je suis la procédure décrite dans la faq c++ et j'ai un soucis :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      istringstream   line;
      istringstream   iss;
      string            temp;
      double           value;
     
      //(...)
     
      std::getline( line, temp, tabul );
      iss.str( temp );
      // iss contient 6,4
      iss >> value;
      // value contient 6.0
    la partie décimale n'est pas gardée..

    J'ai essayé de remplacer le ',' par un '.' mais pas plus de succès.

    Qu'est ce qui cloche ?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Points : 108
    Points
    108
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    J'ai essayé de remplacer le ',' par un '.' mais pas plus de succès.
    Bizarre... c'est un problème de locale, pourtant, non?
    As-tu essayé avec un "." et en ajoutant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iss.imbue(locale("C"));
    avant l'extraction de value?

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 708
    Points
    30 708
    Par défaut
    Salut,

    Le problème est tout simplement que... la notation des réels se fait à la manière anglaise

    Cela signifie que, lors de la convertion:
    • 6.04 représente une valeur réelle
    • 6,04 en représente deux

    La solution est donc, une fois que tu es sur que tu as affaire à un réel, de remplacer, tout simplement, la virgule par un point, du moins, si tu veux que la notation "francaise" soit prise en compte

  4. #4
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par koala01 Voir le message
    La solution est donc, une fois que tu es sur que tu as affaire à un réel, de remplacer, tout simplement, la virgule par un point
    Citation Envoyé par NiamorH
    J'ai essayé de remplacer le ',' par un '.' mais pas plus de succès.
    Je précise que je suis sous VC6.

    Mais je viens de tester sous visual 2005 et c'est effectivement la solution. J'ai peut être mal fait mon test, je retesterai demain.

    Citation Envoyé par Biozic
    iss.imbue(locale("C"));
    J'essaierai demain aussi. merci.

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 951
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 951
    Points : 5 671
    Points
    5 671
    Par défaut
    Sie,
    Citation Envoyé par koala01 Voir le message
    ...
    La solution est donc, une fois que tu es sur que tu as affaire à un réel, de remplacer, tout simplement, la virgule par un point, du moins, si tu veux que la notation "francaise" soit prise en compte
    Ah bon, maintenant, en français on met un point comme séparateur des décimales.

    Comme je ne suis pas au courant, je suppose que ça vient de sortir ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Côte d'Or (Bourgogne)

    Informations forums :
    Inscription : Mai 2005
    Messages : 92
    Points : 108
    Points
    108
    Par défaut
    Citation Envoyé par koala01 Voir le message
    La solution est donc, une fois que tu es sur que tu as affaire à un réel, de remplacer, tout simplement, la virgule par un point, du moins, si tu veux que la notation "francaise" soit prise en compte
    Si le flux d'entrée contient des réels formatés "à la française", on doit pouvoir, en choisissant convenablement la locale, se passer de faire un remplacement explicite. Exception (à confirmer): si il y a un séparateur de millier, comme un espace, l'extraction par >> risque de tomber à l'eau.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 708
    Points
    30 708
    Par défaut
    Citation Envoyé par Biozic Voir le message
    Si le flux d'entrée contient des réels formatés "à la française", on doit pouvoir, en choisissant convenablement la locale, se passer de faire un remplacement explicite. Exception (à confirmer): si il y a un séparateur de millier, comme un espace, l'extraction par >> risque de tomber à l'eau.
    Ce n'est pas impossible...

    Cependant, le mieux serait quand même, selon moi, de juste veiller à ce que les informations soient écrites de la manière dont on s'attend à ce qu'elles soient lues "nativement" par l'application, c'est à dire, sans espace entre les millilers, et avec un point comme indicateur de partie décimale...

    Il sera en effet bien plus simple, à mon sens, d'envisager d'adapter la valeur lue au cas où son affichage est nécessaire, de manière a permettre une compréhension "instinctive" de la valeur que de commencer à la maintenir dans un fichier sous cette forme non comprise par l'ordinateur et de devoir la convertir deux fois:
    • une fois pour que le pc la comprenne
    • une fois pour que l'utilisateur ne se méprenne pas sur la valeur qu'il lit à l'écran

    Maintenant, ce n'est jamais que mon avis perso... Mais je le partage

  8. #8
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Ceci marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iss.imbue( std::locale( "French_france" ) );
    Je vais donc l'utiliser.

    Dans mon cas, il n'est pas possible de modifier la source du probleme en remplaçant les virgules par des points pour les valeurs du fichier lu car ce fichier m'est envoyé par un autre organisme et je dois le traiter tel quel.

    Je pourrais les remplacer avec de tenter l'opérateur >> ( je pense que j'ai mal fait mon premier test ) mais j'aime bien cette solution avec la locale.

    Merci à tous.

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    J'ai un très gros problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iss.imbue( std::locale( "French_france" ) );
    Ce code change la locale pour toute l'appli...
    Ailleurs dans l'appli, sprintf est affecté et formatte maintenant l'affichage avec des virgules à la place des points...

    Pourquoi, en appellant une méthode membre du flux, j'ai autant d'effets de bords ? Cela se limite-t-il à mon appli ou cela affectera-t-il mon systeme d'exploitation aussi ?

    Je ne veux pas remettre l'ancienne locale après traitement car mon appli est multithread et pourrait être affectée pendant le traitement.

  10. #10
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    J'ai un très gros problème :
    Ailleurs dans l'appli, sprintf est affecté et formatte maintenant l'affichage avec des virgules à la place des points...

    Pourquoi, en appellant une méthode membre du flux, j'ai autant d'effets de bords ? Cela se limite-t-il à mon appli ou cela affectera-t-il mon systeme d'exploitation aussi ?

    Je ne veux pas remettre l'ancienne locale après traitement car mon appli est multithread et pourrait être affectée pendant le traitement.
    Pour la gestion des locales, la librairie standard C++ s'appuie sur la librairie C. Le changement de la locale a un effet sur l'application, mais pas sur le système (ce quie tu peux vérifier en lançant 2 instances de ton application, l'une avec le changement, l'autre sans).

  11. #11
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Et bien je dis bouh.
    Ce n'est pas le comportement que j'espérais. Y a-t-il une alternative standard ?

    Mon but est seulement de lire un double à partir d'un fichier texte. Le best serait de pouvoir lire les nombres avec des virgules ET ceux avec des points, des fois qu'il y en aurait cachés dans le fichier.

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    J'ai un très gros problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iss.imbue( std::locale( "French_france" ) );
    Ce code change la locale pour toute l'appli...
    Je suis surpris, car il n'est pas sensé faire ça. Pour vérifier, j'ai effectué le test (VC++9) :

    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
    #include <iostream>
    #include <stdexcept>
     
    using namespace std;
     
    void f()
    {
    	cout << 3.14 << endl;;
    	printf("%f\n", 3.14);
    }
     
     
    int main()
    {
    	f();
    	cout.imbue(locale("French_france"));
    	f();
    	cout.imbue(locale::classic());
    	f();
    	locale::global(locale("French_france"));
    	f();
    }
    Et j'obtiens bien le résultat attendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    3.14
    3.140000
    3,14
    3.140000
    3.14
    3.140000
    3.14
    3,140000

  13. #13
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    J'ai le même résultat que toi sur VS2005, j'ai testé avec istringstream et sprintf plutôt que cout et printf pour coller plus à mon cas.
    Peut-être est-ce encore une implémentation foireuse de VC++6...
    Heureusement la migration vers VS2008 est un objectif qu'on réussit à fixer.

    Loic, si je veux pourvoir lire à partir d'un fichier texte, sans le prétraiter, des doubles écrits avec parfois une virgule et parfois un point, vois-tu un moyen simple ? (finalement c'est pas si mal les fichiers binaires, on a juste à se préoccuper de l'endianess de la machine qui lit)

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    [QUOTE=NiamorH;3031138]Loic, si je veux pourvoir lire à partir d'un fichier texte, sans le prétraiter, des doubles écrits avec parfois une virgule et parfois un point, vois-tu un moyen simple ?[quote]
    Simple ? Non. Mais je ne suis pas spécialiste de la chose.

    Le mieux que je puisse voir, si le but est de packager ça pour ne plus avoir à s'en soucier par la suite, ce serait de définir ta propre facette num_get (en faisant un copier/coller/modifier de celle déjà présente dans ta bibliothèque standard), qui considère les deux signes comme un séparateur décimal (et qui ignore les séparateurs de milliers, à moins que tu aies aussi cette contrainte ?).

    Si le but est d'arriver à un résultat ponctuel, je lirais d'abord le nombre comme un simple mot dans un string, puis utiliserait deux istringstream, pour le lire dans les deux langues, et garderait le résultat qui ne laisse pas de caractères non lus.


    Citation Envoyé par NiamorH Voir le message
    (finalement c'est pas si mal les fichiers binaires, on a juste à se préoccuper de l'endianess de la machine qui lit)
    Pour moi, la distinction binaire/textuel a toujours été un peu secondaire. La première distinction étant : Les fichiers sont-il prévus pour être aussi lus/écrits par des humains.

  15. #15
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Si le but est d'arriver à un résultat ponctuel, je lirais d'abord le nombre comme un simple mot dans un string, puis utiliserait deux istringstream, pour le lire dans les deux langues, et garderait le résultat qui ne laisse pas de caractères non lus.
    Pas mal.

    Citation Envoyé par JolyLoic Voir le message
    Le mieux que je puisse voir, si le but est de packager ça pour ne plus avoir à s'en soucier par la suite, ce serait de définir ta propre facette num_get (en faisant un copier/coller/modifier de celle déjà présente dans ta bibliothèque standard), qui considère les deux signes comme un séparateur décimal (et qui ignore les séparateurs de milliers, à moins que tu aies aussi cette contrainte ?).
    Peut-être encore mieux.

    Merci pour ces pistes !

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/01/2009, 11h30
  2. Problème de conversion String en Double
    Par eighty_three dans le forum Langage
    Réponses: 7
    Dernier message: 19/06/2008, 10h41
  3. conversion string en double
    Par pouletator dans le forum Général Python
    Réponses: 4
    Dernier message: 24/10/2007, 11h35
  4. conversion string en double
    Par kakrocq dans le forum C++/CLI
    Réponses: 4
    Dernier message: 11/04/2007, 14h54
  5. conversion string en double
    Par zmatz dans le forum SL & STL
    Réponses: 2
    Dernier message: 14/10/2005, 23h46

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