french to english numeric conversion

Discussion in 'C++' started by jd, Apr 13, 2006.

  1. jd

    jd Guest

    I have just spent the past week reading up on locales in books by Josuttis
    and Stroustrup. As a simple test of locales, I prepared the following
    source code below. The purpose is to convert the French decimal number
    1.234,567 to the English equivalent of 1,234.567.


    std::locale oFrenchLocale( "French_Canada.1252" );
    std::string oS = "1.234,456";
    std::istringstream oISS( oS );
    std::locale oOldLocale = oISS.imbue( oFrenchLocale );
    double dValue;
    oISS >> dValue;
    oISS.imbue( oOldLocale );
    std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;

    The output is:
    string=1.234,456
    dValue=1

    I was expecting dValue to have a value of 1,234.567 but instead it only has
    a value of 1. Would someone kindly provide me with the mistake I am making.

    Thanks in advance.

    Ian
     
    jd, Apr 13, 2006
    #1
    1. Advertising

  2. jd wrote:
    > I have just spent the past week reading up on locales in books by
    > Josuttis and Stroustrup. As a simple test of locales, I prepared the
    > following source code below. The purpose is to convert the French
    > decimal number 1.234,567 to the English equivalent of 1,234.567.
    >
    >
    > std::locale oFrenchLocale( "French_Canada.1252" );
    > std::string oS = "1.234,456";
    > std::istringstream oISS( oS );
    > std::locale oOldLocale = oISS.imbue( oFrenchLocale );
    > double dValue;
    > oISS >> dValue;

    ^^^^^^^^^^^^^^^^^ Let's call this "line six"

    > oISS.imbue( oOldLocale );
    > std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;
    >
    > The output is:
    > string=1.234,456
    > dValue=1
    >
    > I was expecting dValue to have a value of 1,234.567 but instead it
    > only has a value of 1. Would someone kindly provide me with the
    > mistake I am making.


    I am not very proficient in locales, but I suspect that the "thousands"
    separator is not being accepted as part of the number (and ignored) and
    instead is treated as a field separator so that the input on "line six"
    only reads the "1" and stops. Try dropping the period from the string
    making it

    std::string oS = "1234,456";

    ..

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 13, 2006
    #2
    1. Advertising

  3. jd

    Alex Buell Guest

    On Wed, 12 Apr 2006 19:58:16 -0400 "Victor Bazarov"
    <> waved a wand and this message magically
    appeared:

    > > std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;


    Which one's better, '<< oS <<' or '<< oS.c_str()'?

    --
    http://www.munted.org.uk

    Take a nap, it saves lives.
     
    Alex Buell, Apr 13, 2006
    #3
  4. Alex Buell wrote:
    > On Wed, 12 Apr 2006 19:58:16 -0400 "Victor Bazarov"
    > <> waved a wand and this message magically
    > appeared:
    >
    >>> std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;

    >
    > Which one's better, '<< oS <<' or '<< oS.c_str()'?


    I am not sure... Lemme see... <leafing through the Standard>
    I can't find anything that would make "<< oS" valid... But it compiles
    with online Comeau... Whatever. Too lazy to figure it out.

    I prefer fewer implicit conversions. That's why I'd probably use the
    latter.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 13, 2006
    #4
  5. jd

    jd Guest

    Hello Victor,

    The result is the same regardless of whether or not the period is removed.
    I am obviously missing something simple in the Josuttis and Stroustrup books
    and spend more time trying to figure out what this is.

    I would nevertheless appreciate any suggestions or comments.

    Ian
     
    jd, Apr 13, 2006
    #5
  6. jd

    peter koch Guest

    Victor Bazarov skrev:

    > Alex Buell wrote:
    > > On Wed, 12 Apr 2006 19:58:16 -0400 "Victor Bazarov"
    > > <> waved a wand and this message magically
    > > appeared:
    > >
    > >>> std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;

    > >
    > > Which one's better, '<< oS <<' or '<< oS.c_str()'?

    >
    > I am not sure... Lemme see... <leafing through the Standard>
    > I can't find anything that would make "<< oS" valid... But it compiles
    > with online Comeau... Whatever. Too lazy to figure it out.


    Well... surely you can stream a std::string to a stream! Perhaps you
    should have searched for std::basic_string (as both streams and strings
    are templated)?
    >
    > I prefer fewer implicit conversions. That's why I'd probably use the
    > latter.


    What implicit conversion did you have in mind? from string to char*?
    More news for me!
    >
    > V
    > --

    /Peter
     
    peter koch, Apr 13, 2006
    #6
  7. jd

    Ian Guest

    Hello Victor,

    When I change the region on my computer to Canadian French, the thousand
    separator is a space character. So, I may be wrong but removing the decimal
    from the string does not currently appear to be an option.
    Ian
     
    Ian, Apr 13, 2006
    #7
  8. peter koch wrote:
    > Victor Bazarov skrev:
    >
    >> Alex Buell wrote:
    >>> On Wed, 12 Apr 2006 19:58:16 -0400 "Victor Bazarov"
    >>> <> waved a wand and this message magically
    >>> appeared:
    >>>
    >>>>> std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;
    >>>
    >>> Which one's better, '<< oS <<' or '<< oS.c_str()'?

    >>
    >> I am not sure... Lemme see... <leafing through the Standard>
    >> I can't find anything that would make "<< oS" valid... But it
    >> compiles with online Comeau... Whatever. Too lazy to figure it out.

    >
    > Well... surely you can stream a std::string to a stream!


    'oS' is an object of type 'ostringstream', not 'string'.

    > Perhaps you
    > should have searched for std::basic_string (as both streams and
    > strings are templated)?


    Perhaps you do me a favour and post the results of your own research?
    It would be best, trust me.

    >> I prefer fewer implicit conversions. That's why I'd probably use the
    >> latter.

    >
    > What implicit conversion did you have in mind? from string to char*?
    > More news for me!


    It would seem so...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 13, 2006
    #8
  9. jd wrote:
    > The result is the same regardless of whether or not the period is
    > removed.


    Please post the minimal compilable program so we can see and test it.

    > I am obviously missing something simple in the Josuttis and
    > Stroustrup books and spend more time trying to figure out what this
    > is.


    FAQ 5.8.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 13, 2006
    #9
  10. jd

    peter koch Guest

    Victor Bazarov skrev:

    > peter koch wrote:
    > > Victor Bazarov skrev:
    > >
    > >> Alex Buell wrote:
    > >>> On Wed, 12 Apr 2006 19:58:16 -0400 "Victor Bazarov"
    > >>> <> waved a wand and this message magically
    > >>> appeared:
    > >>>
    > >>>>> std::cout << "\n string=" << oS.c_str() << "\n dValue=" << dValue;
    > >>>
    > >>> Which one's better, '<< oS <<' or '<< oS.c_str()'?
    > >>
    > >> I am not sure... Lemme see... <leafing through the Standard>
    > >> I can't find anything that would make "<< oS" valid... But it
    > >> compiles with online Comeau... Whatever. Too lazy to figure it out.

    > >
    > > Well... surely you can stream a std::string to a stream!

    >
    > 'oS' is an object of type 'ostringstream', not 'string'.


    That would explain your confusion, but if you reread the original post,
    you'll notice that oS is declared as:

    std::string oS = "1.234,456";

    and I do not see any post redefining that variable.

    >
    > > Perhaps you
    > > should have searched for std::basic_string (as both streams and
    > > strings are templated)?

    >
    > Perhaps you do me a favour and post the results of your own research?
    > It would be best, trust me.


    Well.... it only took a few minutes verifying I was right (that was
    before I saw that you believed oS to not be a string).

    >
    > >> I prefer fewer implicit conversions. That's why I'd probably use the
    > >> latter.

    > >
    > > What implicit conversion did you have in mind? from string to char*?
    > > More news for me!

    >
    > It would seem so...


    Apart from this, I'm quite sure that there is no c_str function un a
    stringstream, Perhaps I'll look that one up.

    >
    > V
    > --


    /Peter
     
    peter koch, Apr 13, 2006
    #10
  11. peter koch wrote:
    > [... explanation redacted...]
    >> Perhaps you do me a favour and post the results of your own research?
    >> It would be best, trust me.

    >
    > Well.... it only took a few minutes verifying I was right (that was
    > before I saw that you believed oS to not be a string).


    Thanks. That's what was missing from your post before.

    Yes, I apparently mistook 'oS.c_str()' for 'oISS.str()'. Happens.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Apr 13, 2006
    #11
  12. I replied in c.l.c++.m already, but you'll most likely see the
    answer quicker in here.

    Ian <> wrote:

    > When I change the region on my computer to Canadian French, the
    > thousand separator is a space character.


    On my system, it is a different space character (0xa0) than the one
    I get from the space bar (0x20).

    > removing the decimal from the string does not currently appear to be
    > an option.


    Do you mean changing the dot to the 'official' seperator is no
    option?

    If forcing the user to type Alt+0160 to get that space is not an
    option, replace all regular spaces with the real thousands seperator
    before proceeding (std::string::replace).

    Working without a thousands seperator also works as well (ie.
    "1000,10" for the French locale)

    If you insist on using the dot, you are using the wrong locale.
    Ergo, you need to use a different locale, where the dot *is* the
    thousands seperator (German locale for example).

    hth
    --
    jb

    (reply address in rot13, unscramble first)
     
    Jakob Bieling, Apr 14, 2006
    #12
  13. jd

    Ian Guest

    >
    >> When I change the region on my computer to Canadian French, the
    >> thousand separator is a space character.

    >
    > On my system, it is a different space character (0xa0) than the one I
    > get from the space bar (0x20).
    >> removing the decimal from the string does not currently appear to be
    >> an option.

    >
    > Do you mean changing the dot to the 'official' seperator is no option?


    The suggestion was to change the string "1.234,567" to "1234,567" (i.e.
    remove the dot separator).


    > Working without a thousands seperator also works as well (ie. "1000,10"
    > for the French locale)
    >

    On my system, the thousandth character is the space character so the French
    equivalent of 1,234.567 is
    1 234,567. Unfortunately, as mentioned in my previous posting, the number
    parsed is '1' and not the correct
    decimal number of 1234.567.

    Ian
     
    Ian, Apr 17, 2006
    #13
  14. Ian <> wrote:

    > On my system, the thousandth character is the space character so the
    > French equivalent of 1,234.567 is
    > 1 234,567. Unfortunately, as mentioned in my previous posting, the
    > number parsed is '1' and not the correct
    > decimal number of 1234.567.


    You did not get my point. My point was, there may be *two*
    characters visually representing the *same* space character depending on
    the code-page, but with a *different* value. When you use the wrong one,
    you get wrong results.

    Try this and post the output:

    #include <fstream>
    #include <iostream>

    int main ()
    {
    unsigned char tmp [] = { 0x20, 0xa0, 0x00 };
    std::cout << tmp << std::endl;

    std::eek:fstream f ("test.txt");
    f << tmp;
    f.close ();
    }

    In the std output (from 'cout') I see a space followed an accented
    a. But in the file I see *two* spaces. The *second* space is the space I
    need to use for the currency and your code works as it is.

    Now I do not know if this may be a different character on your
    platform. If the above does not give you the results I get, check your
    regional settings. You might be able to find a sample output (Windows
    has this, for example) of how the regional settings will effect time,
    date and currency display. Copy it and look at it in a hex editor. Try
    the above first, tho.

    And for try-out: " " (regular space) " " (so called 'no-break
    space'). I used "Central Europe (Windows)" encoding, so hopefully this
    character is properly transmitted.

    hth
    --
    jb

    (reply address in rot13, unscramble first)
     
    Jakob Bieling, Apr 17, 2006
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim Royal

    Dynamic English/French links

    Jim Royal, Jan 12, 2005, in forum: HTML
    Replies:
    6
    Views:
    467
    Jim Royal
    Jan 13, 2005
  2. F. GEIGER
    Replies:
    3
    Views:
    373
    F. GEIGER
    Jul 18, 2004
  3. F. GEIGER
    Replies:
    3
    Views:
    813
    F. GEIGER
    Aug 6, 2004
  4. Pater Maximus
    Replies:
    1
    Views:
    348
    Ian Parker
    Oct 20, 2004
  5. Tim Golden
    Replies:
    1
    Views:
    342
    Pater Maximus
    Oct 20, 2004
Loading...

Share This Page