431,661 Members | 779 Online
Need help? Post your question and get tips & solutions from a community of 431,661 IT Pros & Developers. It's quick & easy.

# french to english numeric conversion

 P: n/a 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 Apr 13 '06 #1
13 Replies

 P: n/a 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 Apr 13 '06 #2

 P: n/a 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. Apr 13 '06 #3

 P: n/a 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... 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 Apr 13 '06 #4

 P: n/a 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... 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 Apr 13 '06 #5

 P: n/a 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 Apr 13 '06 #6

 P: n/a 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... 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 Apr 13 '06 #7

 P: n/a 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 Apr 13 '06 #8

 P: n/a 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 Apr 13 '06 #9

 P: n/a 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... 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 Apr 13 '06 #10

 P: n/a 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 Apr 13 '06 #11

 P: n/a 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) Apr 14 '06 #12

 P: n/a > 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 Apr 17 '06 #13

 P: n/a 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 #include int main () { unsigned char tmp [] = { 0x20, 0xa0, 0x00 }; std::cout << tmp << std::endl; std::ofstream 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) Apr 17 '06 #14

### This discussion thread is closed

Replies have been disabled for this discussion.