C++ Error “failure: locale::facet::_S_create_c_loc

2019-03-30 08:59发布

问题:

I seem to have a problem with locales in C++. When I run my programm from within Eclipse, it all works fine. However, when I try to run from the command line, I keep getting this error:

failure: locale::facet::_S_create_c_locale name not valid

This is the code that triggers the error:

// Set up UTF8 file stream
string fileName = "./sz.txt";
wifstream inFileStream;

try {
    setlocale(LC_ALL, "");
    inFileStream.open(fileName.c_str());
    inFileStream.imbue(locale(""));
    if(!inFileStream) {
    return EXIT_FAILURE;
    }
}
catch (const std::exception &exc) {
    wcout << "Error while trying to create UTF8 file stream." << endl;
    std::cerr << exc.what() << endl;
    if( inFileStream.is_open() )
        inFileStream.close();

    return EXIT_FAILURE;
}

The output of "locale" gives the following:

LANG="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_ALL="de_DE.UTF-8"

I have also tried to use "de_DE.UTF-8" as the locale string instead of "" (the way it should be actually), but this gives me the same error.

And strangely enough, the program works fine when run from within Eclipse. I am using g++ to compile from the command line with the following version:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin12.4.0 Thread model: posix

Any idea what might be wrong here?

Cheers,

Martin

回答1:

failure: locale::facet::_S_create_c_locale name not valid

This failure is typical on non-GNU platforms where GCC does not have good enough locale support. See the manual and the --enable-clocale libstdc++ option description there:

Select a target-specific underlying locale package. The choices are 'ieee_1003.1-2001' to specify an X/Open, Standard Unix (IEEE Std. 1003.1-2001) model based on langinfo/iconv/catgets, 'gnu' to specify a model based on functionality from the GNU C library (langinfo/iconv/gettext) (from glibc, the GNU C library), 'generic' to use a generic "C" abstraction which consists of "C" locale info, 'newlib' to specify the Newlib C library model which only differs from the 'generic' model in the handling of ctype, or 'darwin' which omits the wchar_t specializations needed by the 'generic' model.

If not explicitly specified, the configure process tries to guess the most suitable package from the choices above. The default is 'generic'. On glibc-based systems of sufficient vintage (2.3 and newer), 'gnu' is automatically selected. On newlib-based systems ('--with_newlib=yes') and OpenBSD, 'newlib' is automatically selected. On Mac OS X 'darwin' is automatically selected. This option can change the library ABI.

If you look into to the sources of the libstdc++ library, you will see that except for the 'gnu' model, all other models are pretty much stubs that support only the "C" locale. Some platforms simply do not have thread safe locale support. Other platforms, like Darwin (AFAIK, I do not own or have access to MacOS X Darwin), do provide enough thread-safe locale APIs (xlocale) that should make it possible to implement full C++ locale support in libstdc++. Unfortunately, nobody has done it, yet.