none
std::locale::global(std::locale("zh-CN")) Gets "Bad locale name"??

    Question

  • Hi everyone:

           I'm playing with C/C++ locale recently.
           I've got a program which uses Chinese character as file name or in the path of a file. When using fstream to manipulate files, I choose to use MBCS instead of Unicode, so I have to specify the locale.
          At first I tried setlocale(LC_CTYPE, "chinese") and it works well, however, it's a C-style locale setting, for C++, std::locale::global() is preferable. Unfortunately, I just can't set the correct locale by calling std::locale::global(). I have tried: std::locale::global(std::locale("zh-CN")); but I get a "Bad locale name" exception, it's strange, because "zh-CN" conforms to the specification defined in MSDN(http://msdn.microsoft.com/en-us/library/dd373814(VS.85).aspx). Later I found  std::locale::global(std::locale("Chinese")); works well, then I'm totally confused. Could anybody figure it out?

    Tuesday, April 14, 2009 3:30 AM

Answers

  • The link you gave relates to Win32 and COM development. However, std::locale::global is a function from the C++ Standard Library. See the MSDN doucmentation for locale::global.

    If I understand correctly, the strings which std::locale::global supports are implementation specific. Unfortunately, the link I provided does not show an example using Chinese. However, the example "German_germany" is given. Possibly you'll find that "Chinese_simplified" or "Chinese-simplified" is equivalent to "zh-CN".

    Apache's implementation of the C++ standard library supports "zh_CN". If nothing else works for you, you could try that and see if it works in Microsoft's implementation.

    This could stand to be better documented.

    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:04 AM
    Tuesday, April 14, 2009 6:49 PM
  • I had a look at the locale constructor, which takes _Locname as a parameter. Unfortunately it only gives the same example: German_germany. It does not provide a link to a list of valid _Locname values.

    A few tables which don't seem to provide complete answers, but might help you guess the answer, are:

    http://msdn.microsoft.com/de-de/goglobal/bb896001(en-us).aspx
    http://cpansearch.perl.org/src/MARKOV/Log-Report-0.22/lib/Log/Report/Win32Locale.pm
    http://docs.moodle.org/en/Table_of_locales

    The tables at perl.org and moodle.org may not be directly relevant, but both contain the value "Chinese_China.936", which you could at least try. (936 is the same code page number as found in the MSDN table.)

    I also found a MS Visual C++ example which uses setlocale, but has output which may reveal a useful value for the locale's constructor _Locname parameter: "Chinese_People's Republic of China.936".

    I wonder if there's a MSDN forum which deals with National Language Support (NLS) questions.
    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:05 AM
    Wednesday, April 15, 2009 3:20 PM
  • Language and region strings are documented here .  Source code is in vc\crt\src\getqloc.c.  Culture indentifiers like zh-CN were standardized after the C++ standard library got frozen.  Standards are wonderful, so many to choose from.
    Hans Passant.
    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:05 AM
    Wednesday, April 15, 2009 4:07 PM

All replies

  • The link you gave relates to Win32 and COM development. However, std::locale::global is a function from the C++ Standard Library. See the MSDN doucmentation for locale::global.

    If I understand correctly, the strings which std::locale::global supports are implementation specific. Unfortunately, the link I provided does not show an example using Chinese. However, the example "German_germany" is given. Possibly you'll find that "Chinese_simplified" or "Chinese-simplified" is equivalent to "zh-CN".

    Apache's implementation of the C++ standard library supports "zh_CN". If nothing else works for you, you could try that and see if it works in Microsoft's implementation.

    This could stand to be better documented.

    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:04 AM
    Tuesday, April 14, 2009 6:49 PM
  • Thank you very much.
    You're right, locale is platform-denpedent. I've done lots of search but find nothing about locale definition under Windows Vista Business, could anybody give me some hints.
    Besides that, what should I do if I want to implement something like "setlocale(LC_CTYPE, "chinese")" by std::locale? It lacks documentation as well.
    Wednesday, April 15, 2009 8:54 AM
  • I had a look at the locale constructor, which takes _Locname as a parameter. Unfortunately it only gives the same example: German_germany. It does not provide a link to a list of valid _Locname values.

    A few tables which don't seem to provide complete answers, but might help you guess the answer, are:

    http://msdn.microsoft.com/de-de/goglobal/bb896001(en-us).aspx
    http://cpansearch.perl.org/src/MARKOV/Log-Report-0.22/lib/Log/Report/Win32Locale.pm
    http://docs.moodle.org/en/Table_of_locales

    The tables at perl.org and moodle.org may not be directly relevant, but both contain the value "Chinese_China.936", which you could at least try. (936 is the same code page number as found in the MSDN table.)

    I also found a MS Visual C++ example which uses setlocale, but has output which may reveal a useful value for the locale's constructor _Locname parameter: "Chinese_People's Republic of China.936".

    I wonder if there's a MSDN forum which deals with National Language Support (NLS) questions.
    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:05 AM
    Wednesday, April 15, 2009 3:20 PM
  • Language and region strings are documented here .  Source code is in vc\crt\src\getqloc.c.  Culture indentifiers like zh-CN were standardized after the C++ standard library got frozen.  Standards are wonderful, so many to choose from.
    Hans Passant.
    • Marked as answer by Nancy Shao Thursday, April 16, 2009 8:05 AM
    Wednesday, April 15, 2009 4:07 PM
  • "Chinese_China.936" works. Thank you very much for the help!
    Thursday, April 16, 2009 1:36 AM
  • you can  select "std::locale::global(std::locale(" ")); " .
    Friday, November 06, 2009 2:20 AM