Setting C++ locale for 1 category

Discussion in 'C++' started by Stephen Howe, Oct 10, 2011.

  1. Stephen Howe

    Stephen Howe Guest

    Hi

    I believe that if I do

    std::locale::global(std::locale("C"));

    that now only does change the global C++ locale but it also passes
    through to the C locale as if I had done

    setlocale(LC_ALL, "C");

    But in C I can do

    setlocale(LC_CTYPE, ".1252");

    Now exactly how is done in C++?
    One of C++'s locale constructors is

    locale(const locale& other, const char *name, category cat);

    but I am not interested in other, I am interested in name and
    category.
    How do I set the global locale but just for LC_CTYPE alone?

    Thanks

    Stephen howe
     
    Stephen Howe, Oct 10, 2011
    #1
    1. Advertising

  2. Stephen Howe

    Nobody Guest

    On Mon, 10 Oct 2011 08:29:49 -0700, Stephen Howe wrote:

    > How do I set the global locale but just for LC_CTYPE alone?


    std::locale::global(std::locale(std::locale(), "C", std::locale::ctype));

    This sets the C++ global locale, but I don't know if it's guaranteed to
    set the C locale. It works with g++ on Linux, where std::locale().name()
    returns a string of the form "LC_CTYPE=C;LC_NUMERIC=en_GB;...".

    It's probably safe to assume that it won't work if you construct a locale
    by mixing and matching facets rather than categories.
     
    Nobody, Oct 10, 2011
    #2
    1. Advertising

  3. Stephen Howe

    Stephen Howe Guest

    On Oct 10, 5:54 pm, Nobody <> wrote:
    > On Mon, 10 Oct 2011 08:29:49 -0700, Stephen Howe wrote:
    > > How do I set the global locale but just for LC_CTYPE alone?



    > std::locale::global(std::locale(std::locale(), "C", std::locale::ctype));
    >
    > This sets the C++ global locale, but I don't know if it's guaranteed to
    > set the C locale.


    I have since learnt:
    It is if a name is present ("C").
    If a name is given it then does

    setlocale(LC_ALL, loc.name.c_str());

    So that means the standard is causing an all-category set.
    This looks like a flaw in the C++ standard.

    Stephen Howe
     
    Stephen Howe, Oct 10, 2011
    #3
  4. Stephen Howe

    Nobody Guest

    On Mon, 10 Oct 2011 14:38:13 -0700, Stephen Howe wrote:

    >> > How do I set the global locale but just for LC_CTYPE alone?

    >
    >> std::locale::global(std::locale(std::locale(), "C", std::locale::ctype));
    >>
    >> This sets the C++ global locale, but I don't know if it's guaranteed to
    >> set the C locale.

    >
    > I have since learnt:
    > It is if a name is present ("C").
    > If a name is given it then does
    >
    > setlocale(LC_ALL, loc.name.c_str());
    >
    > So that means the standard is causing an all-category set.


    Correct.

    > This looks like a flaw in the C++ standard.


    It isn't. Well, "flaw" is a bit ambiguous, but the problem which I think
    that you're implying doesn't exist.

    If the current locale happens to be the C locale, then the result of:

    std::locale(std::locale(), "C", std::locale::ctype)

    will actually be the C locale, as you're taking the LC_CTYPE category from
    the C locale and the other categories from the C locale also. The
    implementation recognises this and gives the resulting locale the name
    "C". So there's no error in the resulting locale having the name "C", nor
    in std::locale::global calling setlocale(LC_ALL, "C").

    Even if you construct a "heterogeneous" locale by combining categories
    from different locales, there's no problem with std::locale::global
    calling setlocale(LC_ALL, ...), provided that the complete locale can be
    described by a string which is acceptable to setlocale().

    Bear in mind that the C standard says:

    7.11.1.1 The setlocale function

    Synopsis

    [#1]

    #include <locale.h>
    char *setlocale(int category, const char *locale);

    Description

    ...

    [#7] A null pointer for locale causes the setlocale function
    to return a pointer to the string associated with the
    category for the program's current locale; the program's
    locale is not changed.175)

    [#8] The pointer to string returned by the setlocale
    function is such that a subsequent call with that string
    value and its associated category will restore that part of
    the program's locale. The string pointed to shall not be
    modified by the program, but may be overwritten by a
    subsequent call to the setlocale function.

    ...

    175The implementation shall arrange to encode in a string
    the various categories due to a heterogeneous locale when
    category has the value LC_ALL.

    So, if you create a heterogeneous locale by way of multiple setlocale()
    calls with different categories, setlocale(LC_ALL, NULL) must return a
    string such that setlocale(LC_ALL, str) will restore that locale.

    It only becomes tricky if you want to mix your own setlocale() calls with
    calls to std::locale::global(). The latter calls the former (where
    possible), but the former doesn't touch the C++ global locale. The
    construction which I gave earlier changes a single category of the C++
    locale, then updates the C locale to match it.

    Provided that the C and C++ locales were previously "in sync", the effect
    is "as if" setlocale() had been called for a single category; it updates
    all categories, but only one of them actually differs from its previous
    setting. If the C and C++ locales were out of sync, the call will
    resynchronise them. You might consider that a flaw; I consider it a case
    of "don't do that".

    I think (but don't know for certain) that it should suffice to use:

    std::locale::global(std::locale(setlocale(LC_ALL, NULL)));

    to synchronise the C++ locale to the C locale, in the event that the two
    have become desynchronised by explicit setlocale() calls.
     
    Nobody, Oct 11, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Maurice Hulsman
    Replies:
    1
    Views:
    1,858
    Guus Bosman
    Jul 25, 2004
  2. Replies:
    4
    Views:
    1,006
  3. Gabriel Genellina
    Replies:
    0
    Views:
    705
    Gabriel Genellina
    Feb 18, 2009
  4. Sibylle Koczian
    Replies:
    2
    Views:
    1,123
    Sibylle Koczian
    Nov 20, 2010
  5. Vlastimil Brom
    Replies:
    0
    Views:
    956
    Vlastimil Brom
    Dec 9, 2010
Loading...

Share This Page