std::setlocale(3)
πΈ std::setlocale(3) β the C++ Standard Library page, but make it a group chat πΈ
okay bestie, pull up a chair because today we're talking about std::setlocale β yes it's from the C++ Standard Library manpage set, and yes it's lowkey the main character of "why does my decimal separator look like that" discourse. let's get into it π
β¨ NAME β¨
std::setlocale β literally just std::setlocale. no cap, that's the whole name. iconic minimalism.
β¨ Synopsis β¨
so it lives right here bestie:
Defined in header <clocale>
char* setlocale( int category, const char* locale );
The setlocale function installs the specified system locale β or just a portion of it β as the new C locale. and like, the modifications stay in effect and influence the execution of all locale-sensitive C library functions until the next call to setlocale. that's a lot of power for one tiny function ngl. π«Ά
and if locale is a null pointer? then setlocale just queries the current C locale without modifying it. it's giving "just looking, not touching" energy. π
β¨ Parameters β¨
- category β the locale category identifier, one of the
LC_xxxmacros. may be0. π - locale β a system-specific locale identifier. can be
""for the user-preferred locale, or"C"for the minimal locale. β¨
β¨ Return value β¨
a pointer to a narrow null-terminated string identifying the C locale after applying the changes (if any), OR a null pointer on failure. π
here's the slay part: a copy of the returned string, along with the category used in this call to std::setlocale, may be used later in the program to restore the locale back to the state at the end of this call. so like, save it. it's your receipt. π§Ύ
β¨ Notes β¨
okay this is the part where we get serious for a sec, bestie. π«Ά
during program startup, the equivalent of std::setlocale(LC_ALL, "C"); is executed before any user code is run. so that's already happened before you even showed up. β¨
even though the return type is char*, modifying the pointed-to characters is undefined behavior. i know, i know β the type says you can, the universe says you shouldn't. don't do it. π
because setlocale modifies global state which affects execution of locale-dependent functions, it is undefined behavior to call it from one thread while another thread is executing any of the following functions:
std::fprintfstd::isprintstd::iswdigitstd::localeconvstd::tolowerstd::fscanfstd::ispunctstd::iswgraphstd::mblenstd::toupperstd::isalnumstd::isspacestd::iswlowerstd::mbstowcsstd::towlowerstd::isalphastd::isupperstd::iswprintstd::mbtowcstd::towupperstd::isblankstd::iswalnumstd::iswpunctstd::setlocalestd::wcscollstd::iscntrlstd::iswalphastd::iswspacestd::strcollstd::wcstodstd::isdigitstd::iswblankstd::iswupperstd::strerrorstd::wcstombsstd::isgraphstd::iswcntrlstd::iswxdigitstd::strtodstd::wcsxfrmstd::islowerstd::iswctypestd::isxdigit
that's 43 functions, if you were counting. which i was. π₯
POSIX also defines a locale named "POSIX", which is always accessible and is exactly equivalent to the default minimal "C" locale. so if you see "POSIX" out in the wild, that's just "C" in a little outfit. π
and POSIX also specifies that the returned pointer β not just the contents of the pointed-to string β may be invalidated by subsequent calls to setlocale. so seriously, copy it. don't hoard the pointer. π
β¨ Example β¨
// Run this code
#include <clocale>
#include <cstdio>
#include <ctime>
#include <cwchar>
#include <iterator>
#include <string>
int main()
{
// Make a "deep copy" of current locale name.
std::string prev_loc = std::setlocale(LC_ALL, nullptr);
// The C locale will be UTF-8 enabled English,
// decimal dot will be German,
// date and time formatting will be Japanese.
if (const char* loc = std::setlocale(LC_ALL, "en_US.UTF-8"))
std::wprintf(L"New LC_ALL locale: %s\n", loc);
if (const char* loc = std::setlocale(LC_NUMERIC, "de_DE.UTF-8"))
std::wprintf(L"New LC_NUMERIC locale: %s\n", loc);
if (const char* loc = std::setlocale(LC_TIME, "ja_JP.UTF-8"))
std::wprintf(L"New LC_TIME locale: %s\n", loc);
wchar_t buf[100];
std::time_t t = std::time(nullptr);
std::wcsftime(buf, std::size(buf), L"%A %c", std::localtime(&t));
std::wprintf(L"Number: %.2f\nDate: %Ls\n", 3.14, buf);
// Restore the previous locale.
if (const char* loc = std::setlocale(LC_ALL, prev_loc.c_str()))
std::wprintf(L"Restorred LC_ALL locale: %s\n", loc);
}
β¨ Possible output β¨
New LC_ALL locale: en_US.UTF-8
New LC_NUMERIC locale: de_DE.UTF-8
New LC_TIME locale: ja_JP.UTF-8
Number: 3,14
Date: ζ₯ζζ₯ 2022εΉ΄11ζ06ζ₯ 20ζ40ε59η§
Restorred LC_ALL locale: C
(and yes, Restorred is spelled like that in the original β we keep it exactly as it is. character for character, bestie. π«Ά)
β¨ See also β¨
LC_ALLLC_COLLATELC_CTYPELC_MONETARYLC_NUMERICLC_TIME
β these are the locale categories for std::setlocale (macro constant). the whole fam. π
localeβ the set of polymorphic facets that encapsulate cultural differences (class). yes that's the actual description. fancy. π- C documentation for
setlocale
β¨ External links β¨
- List of Windows locale names.
- List of Linux locale names.
and that's the page, bestie! π this masterpiece came to you courtesy of http://cppreference.com, version/date 2024.06.10, filed under std::setlocale(3) β go forth and set your locales responsibly, and remember: copy the string, not the pointer. mwah! ππ
π¦
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms