french to english numeric conversion

J

jd

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
 
V

Victor Bazarov

jd said:
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
 
V

Victor Bazarov

Alex said:
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
 
J

jd

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
 
P

peter koch

Victor Bazarov skrev:
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!
/Peter
 
I

Ian

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
 
V

Victor Bazarov

peter said:
Victor Bazarov skrev:


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.
What implicit conversion did you have in mind? from string to char*?
More news for me!

It would seem so...

V
 
V

Victor Bazarov

jd said:
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
 
P

peter koch

Victor Bazarov skrev:
'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 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).
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.

/Peter
 
V

Victor Bazarov

peter said:
[... 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
 
J

Jakob Bieling

I replied in c.l.c++.m already, but you'll most likely see the
answer quicker in here.

Ian said:
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
 
I

Ian

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

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
 
J

Jakob Bieling

Ian said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top