How can I set the decimal separator to be a comma?

久未见 提交于 2019-12-28 02:07:01

问题


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 iostreams? 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!