473,396 Members | 1,666 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

std::ostringstream & LC_NUMERIC

Hi,

I am playing with the following C++ piece of code (*). At least on
my system debian/gcc 4.3 it looks like I am not writing out a floating
point separator as a comma. what are the operation affected by the
LC_NUMERIC env var value ?

Thanks
-Mathieu
(*)
#include <sstream>
#include <iostream>
#include <stdlib.h>

int main(int argc, char *argv[])
{
setenv("LC_NUMERIC", "fr_FR", 1);
std::ostringstream os;
double d = 1.2;
os << d;
std::string s = os.str();
std::cout << s << std::endl;
std::string::size_type pos_comma = s.find( "," );
if( pos_comma != std::string::npos )
{
return 1;
}
std::string::size_type pos_dot = s.find( "." );
if( pos_dot == std::string::npos )
{
return 1;
}
std::cout << "dot found" << std::endl;
return 0;
}
Oct 7 '08 #1
2 5280
On Oct 7, 2:49 pm, mathieu <mathieu.malate...@gmail.comwrote:
I am playing with the following C++ piece of code (*). At
least on my system debian/gcc 4.3 it looks like I am not
writing out a floating point separator as a comma. what are
the operation affected by the LC_NUMERIC env var value ?
In C++, nothing. All setting an envirionment variable does is
make it available to your process and its sub-processes (at
least under Unix---what it does outside of your process is
really very system dependent).

What you usually do in C++ is just the opposite; you read the
variable to know how to set your locale. While creating a
locale with the name "" (an empty string) is formally
implementation defined, it is a more or less established
convention, at least under Unix, that this locale will depend on
all of the LC_ environment variables. In other words, you will
use the locale the user specified.
#include <sstream>
#include <iostream>
#include <stdlib.h>
int main(int argc, char *argv[])
{
setenv("LC_NUMERIC", "fr_FR", 1);
This could affect creating a locale with the empty string, but
the main reason you would want to do this would be to inform
sub-processes to use the "fr_FR" locale.
std::ostringstream os;
double d = 1.2;
os << d;
std::string s = os.str();
std::cout << s << std::endl;
std::string::size_type pos_comma = s.find( "," );
if( pos_comma != std::string::npos )
{
return 1;
}
std::string::size_type pos_dot = s.find( "." );
if( pos_dot == std::string::npos )
{
return 1;
}
std::cout << "dot found" << std::endl;
return 0;
}
And you've never touched the actual locales used by your
program. In general:

-- A locale (i.e. std::locale) object created with the empty
string as a name will normally correspond to the "locale"
active in whatever process invoked you---under Unix, it will
normally use the LC_ environment variables, and perhaps
LANG, to determine this.

-- There is a global locale, used whenever you do not specify a
locale. On program start up, this is set to the "C" locale
(which might be appropriate for parsing C++ sources, but not
for much else); you can change it by calling
std::locale::global with the locale you want as the global
locale.

Combined with the previous point: almost every program which
generates human output should start with:
std::locale::global( std::locale( "" ) ) ;
Or if you really want to force a French locale, even for
users who don't want it:
std::locale::global( std::locale( "fr_FR" ) ) ;
(assuming the Unix naming conventions for locales.)

-- For any given IO, you can force the locale just for that
stream, by using imbue. Thus, if you've done the above (and
thus don't really know what the global locale is), but want
to output C++ code (for example), you should imbue the file
with the "C" locale; either:
output.imbue( std::locale( "C" ) ) ;
or:
output.imbue( std::locale::classic() ) ;
(which uses a special static member function to get this
very special locale). Similarly, if you want to force
output in the French locale for just this file:
output.imbue( std::locale( "fr_FR" ) ) ;

-- Finally, you can mix locales. If you want the classic
locale in general, but you want numbers formatted according
to the rules in French, you can create a custom locale for
this, e.g.
std::locale( std::locale::classic(),
"fr_FR",
std::locale::numeric )
In otherwords, copy std::locale::classic() (the first
argument), except for the numeric category (the third
argument, which can be an or'ed list of facets), which is
taken from the locale named "fr_FR".

In general, this is fairly tricky, however, and you have to
know what you are doing, and how the different "facets"
interact. (Each category is implemented by one or more
facets.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 8 '08 #2
On Oct 8, 11:00 am, James Kanze <james.ka...@gmail.comwrote:
On Oct 7, 2:49 pm, mathieu <mathieu.malate...@gmail.comwrote:
I am playing with the following C++ piece of code (*). At
least on my system debian/gcc 4.3 it looks like I am not
writing out a floating point separator as a comma. what are
the operation affected by the LC_NUMERIC env var value ?

In C++, nothing. All setting an envirionment variable does is
make it available to your process and its sub-processes (at
least under Unix---what it does outside of your process is
really very system dependent).

What you usually do in C++ is just the opposite; you read the
variable to know how to set your locale. While creating a
locale with the name "" (an empty string) is formally
implementation defined, it is a more or less established
convention, at least under Unix, that this locale will depend on
all of the LC_ environment variables. In other words, you will
use the locale the user specified.
#include <sstream>
#include <iostream>
#include <stdlib.h>
int main(int argc, char *argv[])
{
setenv("LC_NUMERIC", "fr_FR", 1);

This could affect creating a locale with the empty string, but
the main reason you would want to do this would be to inform
sub-processes to use the "fr_FR" locale.
std::ostringstream os;
double d = 1.2;
os << d;
std::string s = os.str();
std::cout << s << std::endl;
std::string::size_type pos_comma = s.find( "," );
if( pos_comma != std::string::npos )
{
return 1;
}
std::string::size_type pos_dot = s.find( "." );
if( pos_dot == std::string::npos )
{
return 1;
}
std::cout << "dot found" << std::endl;
return 0;
}

And you've never touched the actual locales used by your
program. In general:

-- A locale (i.e. std::locale) object created with the empty
string as a name will normally correspond to the "locale"
active in whatever process invoked you---under Unix, it will
normally use the LC_ environment variables, and perhaps
LANG, to determine this.

-- There is a global locale, used whenever you do not specify a
locale. On program start up, this is set to the "C" locale
(which might be appropriate for parsing C++ sources, but not
for much else); you can change it by calling
std::locale::global with the locale you want as the global
locale.

Combined with the previous point: almost every program which
generates human output should start with:
std::locale::global( std::locale( "" ) ) ;
Or if you really want to force a French locale, even for
users who don't want it:
std::locale::global( std::locale( "fr_FR" ) ) ;
(assuming the Unix naming conventions for locales.)

-- For any given IO, you can force the locale just for that
stream, by using imbue. Thus, if you've done the above (and
thus don't really know what the global locale is), but want
to output C++ code (for example), you should imbue the file
with the "C" locale; either:
output.imbue( std::locale( "C" ) ) ;
or:
output.imbue( std::locale::classic() ) ;
(which uses a special static member function to get this
very special locale). Similarly, if you want to force
output in the French locale for just this file:
output.imbue( std::locale( "fr_FR" ) ) ;

-- Finally, you can mix locales. If you want the classic
locale in general, but you want numbers formatted according
to the rules in French, you can create a custom locale for
this, e.g.
std::locale( std::locale::classic(),
"fr_FR",
std::locale::numeric )
In otherwords, copy std::locale::classic() (the first
argument), except for the numeric category (the third
argument, which can be an or'ed list of facets), which is
taken from the locale named "fr_FR".

In general, this is fairly tricky, however, and you have to
know what you are doing, and how the different "facets"
interact. (Each category is implemented by one or more
facets.)
Thanks ! That's extremely detailed :)

Since I am a just library author I can not rely on the fact that my
user will start their main program with
std::locale::global( std::locale( "" ) ) ;

Instead I'll have to make sure any o*stream are created (within the
lib, or externally by the user) with
os.imbue(std::locale::classic());

Regards
-Mathieu
Oct 8 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Eric Boutin | last post by:
Hi ! I have a strange problem with a std::ostringstream.. code : #include <sstream> /*...*/ std::ostringstream ss(); ss << "\"\"" << libpath << "\"\" \"\"" << argfilename << "\"\"...
3
by: Chris | last post by:
Hi, I'm playing/developing a simple p2p file sharing client for an existing protocol. A 2 second description of the protocol is Message Length = int, 4 bytes Message Code = int, 4 bytes...
6
by: Christopher Benson-Manica | last post by:
Is there anything that one can do to a std::ostringstream that would make its destructor explode? I'm basically doing { std::ostringstream ss, msg; // do BUNCHES of stuff with ss and msg ...
5
by: Simon Pryor | last post by:
I am having some strange problems using std::ostringstream. The simple stuff works okay, but trying to use: std::ostringstream::str(const std::string&) or:...
1
by: Jason Heyes | last post by:
I would like to have std::cout redirect its output to a std::ostringstream. Can this be done? Help is appreciated.
1
by: Voronkov Konstantin | last post by:
Hello all! std::ostringstream stream; stream << 8080; std::string str = stream.str(); // str == "8 080" The code shown above in mine big program result the str variable value to
2
by: bob | last post by:
For reasons that are irrelevant , we cannot use sprintf to do conversions between doubles, ints etc. to char*. We're using the std::ostringstream type. Basically we have a function that takes a...
4
by: Olaf van der Spek | last post by:
Hi, I'm using ostringstream and I'd like to generate \r\n line ends instead of \n ones. Is there a flag for this? Or should I just insert the \r myself?
25
by: Bala2508 | last post by:
Hi, I have a C++ application that extensively uses std::string and std::ostringstream in somewhat similar manner as below std::string msgHeader; msgHeader = "<"; msgHeader += a; msgHeader...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.