问题
I would like to read and write pi as 3,141592
instead of 3.141592
, as using the comma is common in many European countries. How can I accomplish this with iostream
s? In other words
cout << 3.141592;
should print
3,141592
to standard output.
回答1:
You should use basic_ios::imbue
to set the preferred locale.
Take a look here: http://www.cplusplus.com/reference/ios/ios_base/imbue/
Locales allow you to use the preferred way by the user, so if a computer in Italy uses comma to separate decimal digits, in the US the dot is still used. Using locales is a Good Practice.
But if you want to explicitly force the use of the comma, take a look here: http://www.cplusplus.com/reference/locale/numpunct/decimal_point/
Here a small example I just made with g++ which enforces the char ',' (passing the separator as template argument is just for fun, not really necessary)
#include <iostream>
#include <locale>
template <class charT, charT sep>
class punct_facet: public std::numpunct<charT> {
protected:
charT do_decimal_point() const { return sep; }
};
int main(int argc, char **argv) {
std::cout.imbue(std::locale(std::cout.getloc(), new punct_facet<char, ','>));
std::cout << "My age is " << 3.1415 << " lightyears.\n";
}
Note that using cout.getloc()
I'm overriding just a single facet in the currently set locale, that is, in the current locale settings of cout, I'm changing only how the punctuation is done.
do_decimal_point
is a virtual function of std::numpunct
that you can redefine to provide your custom separator. This virtual function will be used by numpunct::decimal_point
when printing your number.
回答2:
As @AkiRoss said, you need to use locales. In general, in any
program you write, one of the very first actions in main
should be to set the global locale to the users choice, by doing
something like:
std::locale::global( std::locale( "" ) );
This should be systematic, in every program which interacts with a human user. All files opened after this will automatically be imbued with the correct locale.
Alternatively, you can explicitly specify the locale you want to use:
std::locale::global( std::locale( locale_name ) );
The problem with this is that there is no standard for locale
names. Something like "it_IT.UTF-8"
corresponds to the Posix
standard, and is used on the Internet; Windows has traditionally
used a different format (although recent Windows do seem to
accept this format as well).
Which leaves std::cin
, std::cout
and std::cerr
. These are
opened before you enter main
, and so must be imbued with the
new locale. (To obtain a copy of the current global locale, use
the default constructor of std::locale
.)
Finally, if you're opening any binary files, be aware that they
also will be imbued with the global locale. Which may do code
translation. In such cases, you should imbue them explicitly
with std::locale::classic()
, or create a new locale by merging
the codecvt
facet of std::locale::classic()
with the other
facets of the global locale. (std::locale
has special
functions and constructors for this.)
来源:https://stackoverflow.com/questions/15220861/how-can-i-set-the-decimal-separator-to-be-a-comma