Std::Locale Breakage on MACos 10.6 with Lang=En_Us.Utf-8

std::locale breakage on MacOS 10.6 with LANG=en_US.UTF-8

I have encountered this problem very recently on Ubuntu 14.04 LTS and on a Raspberry Pi running the latest Raspbian Wheezy.

It has nothing to do with OS X, rather with a combination of G++ and Boost (at least up to V1.55) and the default locale settings on certain platforms. There are Boost bug tickets sort of related to this issue, see
ticket #4688 and ticket #5928.

My "solution" was first to do some extra locale setup, as suggested by this AskUbuntu posting:

sudo locale-gen en_US en_US.UTF-8
sudo dpkg-reconfigure locales

But then, I also had to make sure that the environment variable LC_ALL is set to the value of LANG (it is advisable to put this in your .profile):

export LC_ALL=$LANG

In my case I use the locale en_US.UTF-8.

Final remark: the OP said "This program fails when I run this through g++". I understand that this thread was started in 2009, but today there is absolutely no need to use GCC or G++ on the Mac, the much better LLVM/Clang compiler suite is available from Apple free of charge, see the XCode home page.

Setting locales on OS X crashes

I don't think you're using xlocale. I believe that your problem is with libstdc++, which uses a different locale support library that is not supported on OS X, as the question EitanT links to states.

If you switch to libc++ your program will work.

How to use C++ std::locale in MacOS bundle application?

Thank you.

That solved my problem.

#ifdef __APPLE__
// MACOS needs a special routine to get the locale for bundled applications.
if ( getenv( "LANG" ) == nullptr )
{
const char *lang = get_mac_locale( );
setenv( "LANG", lang, 1 );
}

#endif

Now my program runs correctly from both Apple Terminal and as a bundled application.

operator returns failure when I enter a 4-digit number after setting the locale

If you input 1,001, your program should print true.

The en_US locale expects a comma between each group of three digits. Because you didn't provide one, std::num_get::get() sets failbit on std::cin. See the link for more detail, but the relevant excerpts are:

Stage 2: character extraction


If the character matches the thousands separator
(std::use_facet<std::numpunct<charT>>(str.getloc()).thousands_sep())
and the thousands separation is in use at all
std::use_facet<std::numpunct<charT>>(str.getloc()).grouping().length()
!= 0
, then if the decimal point '.' has not yet been accumulated, the
position of the character is remembered, but the character is
otherwise ignored. If the decimal point has already been accumulated,
the character is discarded and Stage 2 terminates.

And

Stage 3: conversion and storage


After this, digit grouping is checked. if the position of any of the thousands separators discarded in Stage
2 does not match the grouping provided by
std::use_facet<std::numpunct<charT>>(str.getloc()).grouping(),
std::ios_base::failbit is assigned to err.

std::locale::facet::_S_create_c_locale name not valid

I ran into same problem last week, I wrote a program to print all supported locale names under Windows OS.

See my answer Print all std::locale names (Windows)

Locale that you are looking for is just "en-US" under Windows.

How to use wstring and wcout to output Chinese words in Xcode?

You don't. Mac, like other Unix systems, uses UTF8 while Windows uses "Unicode" (UTF-16).

You can print that perfectly well on Mac by using string and cout instead of wstring and wcout.

ADDENDUM

This sample works great. Compile with g++ and run as-is.

#include <string>
#include <iostream>

using namespace std;

int main(int arg, char **argv)
{
string text("汉语");
cout << text << endl;

return 0;
}


Related Topics



Leave a reply



Submit