setlocale, _wsetlocale

設定或擷取運行時間地區設定。

語法

char *setlocale(
   int category,
   const char *locale
);

wchar_t *_wsetlocale(
   int category,
   const wchar_t *locale
);

參數

category
地區設定所影響的分類。

locale
地區設定指定名稱。

傳回值

如果指定了 有效的 localecategory ,則函式會傳回與指定 localecategory相關聯的字串指標。 如果自 locale 變數為 NULL,則函式會傳回目前的地區設定。

如果無效的自變數傳遞至任一函式,傳回值為 NULL。 無效自變數的行為如下所示:

函式 參數無效 叫用的處理程序無效,如參數驗證中所述 errno
setlocale category
setlocale locale
_wsetlocale category
_wsetlocale locale

呼叫:

setlocale( LC_ALL, "en-US" );

會設定所有分類,只傳回字串

en-US

您可以複製 setlocale 所傳回的字串,還原程式的地區設定資訊部分。 全域或執行緒區域儲存區可用於 setlocale 所傳回的字串。 對 setlocale 的後續呼叫會覆寫字串,使先前呼叫所傳回的字串指標失效。

備註

使用 setlocale 函式可設定、變更或查詢 localecategory所指定的部分或所有目前的程式地區設定資訊。 locale 會參考位置 (國家/地區和語言) 來讓您自訂程式的某些方面。 有些與地區設定相關的類別含有日期格式和貨幣值的顯示格式。 如果您將 locale 設定為具有電腦上支援之多種形式語言的預設字串,您應檢查 setlocale 傳回值以查看是哪種語言生效。 例如,如果您將 設定 locale"chinese" 傳回值可能是 "chinese-simplified""chinese-traditional"

_wsetlocalesetlocale的寬字元版本, locale 引數與 _wsetlocale 的傳回值是寬字元字串。 否則,_wsetlocalesetlocale 的行為即會相同。

根據預設,此函式的全域狀態會限定於應用程式。 若要變更此行為,請參閱 CRT中的全域狀態。

泛型文字例程對應

TCHAR.H 常規 _UNICODE_MBCS 未定義 _MBCS 定義 _UNICODE 定義
_tsetlocale setlocale setlocale _wsetlocale

category 引數會指定程式地區設定資訊中受影響的部分。 用於 category 的巨集以及所影響的程式部分如下:

category 旗標 Affects
LC_ALL 所有分類,如下所示。
LC_COLLATE strcoll_stricollwcscoll_wcsicollstrxfrm_strncoll_strnicoll_wcsncoll_wcsnicoll 以及 wcsxfrm 函式。
LC_CTYPE 字元處理函式 (除了 isdigitisxdigitmbstowcsmbtowc,這些不會受到影響)。
LC_MONETARY localeconv 函式傳回的貨幣格式資訊。
LC_NUMERIC 格式化輸出例程的小數點字元(例如 printf),用於數據轉換例程,以及所 localeconv傳回的非數位格式資訊。 除了小數點字元之外, LC_NUMERIC 還設定 所傳 localeconv回的千位分隔符和群組控制字串。
LC_TIME strftimewcsftime 函式。

此函式會驗證分類參數。 如果類別參數不是上表中指定的其中一個值,則會叫用無效的參數處理程式,如參數驗證中所述。 如果允許繼續執行,則函式會將 errno 設定為 EINVAL 並傳回 NULL

locale 引數是指向會指定地區設定的字串指標。 如需自變數格式 locale 的詳細資訊,請參閱 地區設定名稱、語言和國家/地區字串。 如果 locale 指向空字串,地區設定即是由實作環境決定的原生環境。 C 的值會指定符合 C 轉譯環境的最小 ANSI。 C 地區設定會假設所有 char 資料類型皆為 1 個位元組,而其值永遠小於 256。

在程式啟動時,將執行與下列陳述式相同的動作:

setlocale( LC_ALL, "C" );

locale 引數可以讀取地區設定名稱、語言字串、語言字串和國家/地區碼、字碼頁或語言字串、國家/地區碼和字碼頁。 可用的地區設定名稱、語言、國家/地區代碼和代碼頁包含 Windows NLS API 支援的所有地區設定名稱。 支援 setlocale 的地區設定名稱集合描述 於地區設定名稱、語言和國家/地區字串。 所 setlocale 支援的語言和國家/地區字串集合會列在 語言字串 和國家 /地區字串中。 我們建議使用內嵌於程式碼或針對儲存體序列化之地區設定字串的效能與維護所適用的地區設定名稱格式。 地區設定名稱字串比語言和國家/地區名稱格式更不容易被作業系統更新變更。

locale 引數呼叫 setlocale 查詢而非設定國際環境時所傳遞的 null 指標。 如果自 locale 變數是 Null 指標,則程式目前的地區設定不會變更。 相反地,setlocale 會傳回與執行緒目前地區設定的 category 相關聯的字串指標。 如果 category 引數是 LC_ALL,函式會傳回表示每種分類之目前設定的字串,並以分號隔開。 例如,呼叫的順序

// Set all categories and return "en-US"
setlocale(LC_ALL, "en-US");
// Set only the LC_MONETARY category and return "fr-FR"
setlocale(LC_MONETARY, "fr-FR");
printf("%s\n", setlocale(LC_ALL, NULL));

傳回

LC_COLLATE=en-US;LC_CTYPE=en-US;LC_MONETARY=fr-FR;LC_NUMERIC=en-US;LC_TIME=en-US

其為與 LC_ALL 分類相關聯的字串。

下列範例與 LC_ALL 分類相關。 任一字串“。OCP“ 和 ”.您可以使用 ACP 來代替代碼頁碼編號,以指定分別使用該地區設定名稱的用戶預設 OEM 代碼頁和用戶預設 ANSI 代碼頁。

  • setlocale( LC_ALL, "" );

    將地區設定設定為從作業系統取得的使用者預設 ANSI 字碼頁的預設值。 地區設定名稱會設定為 所 GetUserDefaultLocaleName傳回的值。 代碼頁會設定為 所 GetACP傳回的值。

  • setlocale( LC_ALL, ".OCP" );

    將地區設定設定為從作業系統取得的目前 OEM 代碼頁。 地區設定名稱會設定為 所 GetUserDefaultLocaleName傳回的值。 代碼頁會設定為 LOCALE_IDEFAULTCODEPAGE 用戶預設地區設定名稱 GetLocaleInfoEx的值。

  • setlocale( LC_ALL, ".ACP" );

    將地區設定設定為從作業系統取得的 ANSI 字碼頁。 地區設定名稱會設定為 所 GetUserDefaultLocaleName傳回的值。 代碼頁會設定為 LOCALE_IDEFAULTANSICODEPAGE 用戶預設地區設定名稱 GetLocaleInfoEx的值。

  • setlocale( LC_ALL, "<localename>" );

    將地區設定為 所 <localename>指示的地區設定名稱。 代碼頁會設定為 LOCALE_IDEFAULTANSICODEPAGE 所指定地區設定名稱 GetLocaleInfoEx的值。

  • setlocale( LC_ALL, "<language>_<country>" );

    將地區設定設定為和 <country>所指示<language>的語言和國家/地區,以及從主機操作系統取得的默認代碼頁。 代碼頁會設定為 LOCALE_IDEFAULTANSICODEPAGE 所指定地區設定名稱 GetLocaleInfoEx的值。

  • setlocale( LC_ALL, "<language>_<country>.<code_page>" );

    將地區設定設定為 、、 和 字串所<language><country>指示的語言、國家/地區和<code_page>代碼頁。 您可以使用各種語言、國家/地區和字碼頁的組合。 例如,此呼叫會以字碼頁 1252 將地區設定設為加拿大法文:

    setlocale( LC_ALL, "French_Canada.1252" );

    此呼叫會以預設 ANSI 字碼頁將地區設定設為加拿大法文:

    setlocale( LC_ALL, "French_Canada.ACP" );

    此呼叫會以預設 OEM 字碼頁將地區設定設為加拿大法文:

    setlocale( LC_ALL, "French_Canada.OCP" );

  • setlocale( LC_ALL, "<language>" );

    將地區設定設定為 所 <language>指示的語言,並使用指定語言的預設國家/地區,以及從主機操作系統取得的國家/地區用戶預設 ANSI 代碼頁。 舉例而言,下列對 setlocale 的呼叫功能是相同的:

    setlocale( LC_ALL, "en-US" );

    setlocale( LC_ALL, "English" );

    setlocale( LC_ALL, "English_United States.1252" );

    我們建議用於效能和維護的第一個格式。

  • setlocale( LC_ALL, ".<code_page>" );

    將代碼頁設定為 所 <code_page>指示的值,以及指定代碼頁的預設國家/地區和語言(如主機操作系統所定義)。

分類必須是 LC_ALLLC_CTYPE 兩者之一,以促使字碼頁變更。 例如,如果主機操作系統的預設國家/地區和語言為 “United States” 和 “English”,則下列兩個 對 的呼叫 setlocale 在功能上相等:

setlocale( LC_ALL, ".1252" );

setlocale( LC_ALL, "English_United States.1252");

如需詳細資訊,請參閱 setlocale C/C++ 預處理器參考中的 pragma 指示詞

函式 _configthreadlocale 可用來控制是否 setlocale 會影響程式中的所有線程地區設定,或只影響呼叫線程的地區設定。

UTF-8 支援

從 Windows 10 版本 1803 (10.0.17134.0)開始,通用 C 運行時間支援使用 UTF-8 代碼頁。 變更表示 char 傳遞至 C 運行時間函式的字串可能需要 UTF-8 編碼中的字串。 若要啟用 UTF-8 模式,請使用 ".UTF8" 作為使用 setlocale時的代碼頁。 例如, setlocale(LC_ALL, ".UTF8") 針對地區設定使用目前的預設 Windows ANSI 代碼頁 (ACP),並將 UTF-8 用於代碼頁。

指定 UTF-8 模式的字串為:

  • 不區分大小寫
  • 連字元 (-) 是選擇性的
  • 它必須位於地區設定名稱的代碼頁部分,因此必須有前置句點 (.),如下列範例所示: "en_US.UTF8"".utf8"

下列範例示範如何指定 UTF-8 字串:

".UTF8"
".UTF-8"
".utf8"
".utf-8"
"en_us.utf8"
"ja_JP.Utf-8"

呼叫 setlocale(LC_ALL, ".UTF8")之後,您可以將 「😊傳遞至 mbtowcs ,並將它正確轉譯為 wchar_t 字串。 先前沒有地區設定可供執行此翻譯。

UTF-8 模式也針對使用預設 Windows ANSI 代碼頁 (ACP) 進行歷程記錄轉譯 char 字串的函式啟用。 例如,使用UTF-8代碼頁時呼叫 _mkdir("😊") 時,會正確地產生具有該 emoji 作為資料夾名稱的目錄,而不是在執行程式之前,要求ACP變更為UTF-8。 同樣地,在該資料夾中呼叫 _getcwd() 會傳回 UTF-8 編碼字串。 為了相容,如果 C 地區設定代碼頁未設定為 UTF-8,仍會使用 ACP。

C 執行時間的下列層面無法使用 UTF-8,因為它們是在程式啟動期間設定,而且必須使用預設的 Windows ANSI 代碼頁 (ACP): __argv_acmdln_pgmptr

先前支援、mbrtoc16mbrtoc32c16rtombc32rtomb 都存在,可在UTF-8窄字串、UTF-16(與 Windows 平臺上的wchar_t編碼方式相同)和UTF-32之間轉譯。 基於相容性考慮,這些 API 仍然只會轉譯至 UTF-8,而不是透過 setlocale設定的代碼頁。

若要在 Windows 10 之前的作業系統上使用這項功能,您必須使用 Windows SDK 或更新版本的 1803 版(10.0.17134.0)靜態連結應用程式本機部署 或連結。 針對 1803 之前的 Windows 10 操作系統(10.0.17134.0),僅支援靜態連結。

需求

常式 必要的標頭
setlocale <locale.h>
_wsetlocale <locale.h><wchar.h>

如需相容性詳細資訊,請參閱相容性

範例

// crt_setlocale.c
//
// This program demonstrates the use of setlocale when
// using two independent threads.
//

#include <locale.h>
#include <process.h>
#include <windows.h>
#include <stdio.h>
#include <time.h>

#define BUFF_SIZE 100

// Retrieve the date in the current
// locale's format.
int get_date(unsigned char* str)
{
    __time64_t ltime;
    struct tm  thetime;

    // Retrieve the current time
    _time64(&ltime);
    _gmtime64_s(&thetime, &ltime);

    // Format the current time structure into a string
    // "%#x" is the long date representation in the
    // current locale
    if (!strftime((char *)str, BUFF_SIZE, "%#x",
                  (const struct tm *)&thetime))
    {
        printf("strftime failed!\n");
        return -1;
    }
    return 0;
}

// This thread sets its locale to the argument and prints the date.
unsigned __stdcall SecondThreadFunc(void* pArguments)
{
    unsigned char str[BUFF_SIZE];
    char * locale = (char *)pArguments;

    // Set the thread locale
    printf("The thread locale is now set to %s.\n",
           setlocale(LC_ALL, locale));

    // Retrieve the date string from the helper function
    if (get_date(str) == 0)
    {
        printf("The date in %s locale is: '%s'\n", locale, str);
    }

    _endthreadex( 0 );
    return 0;
}

// The main thread sets the locale to English
// and then spawns a second thread (above) and prints the date.
int main()
{
    HANDLE          hThread;
    unsigned        threadID;
    unsigned char   str[BUFF_SIZE];

    // Enable per-thread locale causes all subsequent locale
    // setting changes in this thread to only affect this thread.
    _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);

    // Set the locale of the main thread to US English.
    printf("The thread locale is now set to %s.\n",
           setlocale(LC_ALL, "en-US"));

    // Create the second thread with a German locale.
    // Our thread function takes an argument of the locale to use.
    hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc,
                                      (void*)"de-DE", 0, &threadID );

    if (get_date(str) == 0)
    {
        // Retrieve the date string from the helper function
        printf("The date in en-US locale is: '%s'\n\n", str);
    }

    // Wait for the created thread to finish.
    WaitForSingleObject( hThread, INFINITE );

    // Destroy the thread object.
    CloseHandle( hThread );
}
The thread locale is now set to en-US.
The date in en-US locale is: 'Thursday, January 4, 2024'

The thread locale is now set to de-DE.
The date in de-DE locale is: 'Donnerstag, 4. Januar 2024'

另請參閱

地區設定名稱、語言和國家/地區字串
_configthreadlocale
_create_locale, _wcreate_locale
地區設定
localeconv
_mbclen、 、 mblen_mblen_l
strlen、、wcslen_mbslen_mbslen_l、、_mbstrlen_mbstrlen_l
mbstowcs, _mbstowcs_l
mbtowc, _mbtowc_l
_setmbcp
strcoll 函數
strftime、 、 wcsftime_strftime_l_wcsftime_l
strxfrm、 、 wcsxfrm_strxfrm_l_wcsxfrm_l
wcstombs, _wcstombs_l
wctomb, _wctomb_l