Overview

The locale.h header file manages localization settings in programs, affecting the following behaviors:

  • Number formatting
  • Currency formatting
  • Character classification
  • Date and time formatting

It defines several macros:

  • LC_COLLATE: Influences string comparison functions strcoll() and strxfrm().
  • LC_CTYPE: Affects character processing functions.
  • LC_MONETARY: Impacts currency formatting.
  • LC_NUMERIC: Modifies number formatting for printf().
  • LC_TIME: Affects date and time formatting functions strftime() and wcsftime().
  • LC_ALL: Sets all categories to the specified locale.

setlocale()

The function setlocale() sets the current locale.

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

It accepts two parameters: the first indicates the scope (if it’s one of the five category macros, it only affects that category; if LC_ALL, it affects all). The second parameter is usually "C" (default) or "" (local mode).

By default, every program starts with:

1
setlocale(LC_ALL, "C");

To localize formatting, use:

1
setlocale(LC_ALL, "");

Here, the second parameter as an empty string indicates the use of the current environment’s locale.

The second parameter can also be set to a specific format supported by the system, like:

1
setlocale(LC_ALL, "en_US.UTF-8");

However, this reduces portability, as other systems may not support that format. Typically, it’s best to use an empty string to utilize the OS’s current settings.

setlocale() returns a string pointer representing the configured locale. If it fails, it returns NULL. You can also query the current locale by setting the second parameter to NULL:

1
2
3
4
5
char *loc;
loc = setlocale(LC_ALL, NULL);
printf("Starting locale: %s\n", loc);
loc = setlocale(LC_ALL, "");
printf("Native locale: %s\n", loc);

localeconv()

The function localeconv() retrieves detailed information about the current locale settings.

1
struct lconv* localeconv(void);

It returns a pointer to a struct containing various formatting properties:

  • char* mon_decimal_point: Decimal point character (e.g., .).
  • char* mon_thousands_sep: Thousands separator (e.g., ,).
  • char* mon_grouping: Grouping descriptor for currency.
  • char* positive_sign: Positive sign character (e.g., + or empty).
  • char* negative_sign: Negative sign character (e.g., -).
  • char* currency_symbol: Currency symbol (e.g., $).
  • char frac_digits: Number of decimal places for currency.
  • char p_cs_precedes: Indicates if the currency symbol appears before non-negative amounts (1 = yes, 0 = no).
  • char n_cs_precedes: Indicates if the currency symbol appears before negative amounts (1 = yes, 0 = no).
  • char p_sep_by_space: Determines space between non-negative amounts and the currency symbol.
  • char n_sep_by_space: Determines space between negative amounts and the currency symbol.
  • char p_sign_posn: Position of the positive sign.
  • char n_sign_posn: Position of the negative sign.
  • char* int_curr_symbol: International currency symbol (e.g., USD).
  • char int_frac_digits: The value of frac_digits when using the international symbol.
  • char int_p_cs_precedes: The value of p_cs_precedes when using the international symbol.
  • char int_n_cs_precedes: The value of n_cs_precedes when using the international symbol.
  • char int_p_sep_by_space: The value of p_sep_by_space when using the international symbol.
  • char int_n_sep_by_space: The value of n_sep_by_space when using the international symbol.
  • char int_p_sign_posn: The value of p_sign_posn when using the international symbol.
  • char int_n_sign_posn: The value of n_sign_posn when using the international symbol.

Example Program

The following program prints the current system’s locale settings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <locale.h>
#include <string.h>

int main ()
{
setlocale (LC_ALL,"zh_CN");
struct lconv * lc;
lc=localeconv();
printf ("decimal_point: %s\n",lc->decimal_point);
printf ("thousands_sep: %s\n",lc->thousands_sep);
printf ("grouping: %s\n",lc->grouping);
printf ("int_curr_symbol: %s\n",lc->int_curr_symbol);
printf ("currency_symbol: %s\n",lc->currency_symbol);
printf ("mon_decimal_point: %s\n",lc->mon_decimal_point);
printf ("mon_thousands_sep: %s\n",lc->mon_thousands_sep);
printf ("mon_grouping: %s\n",lc->mon_grouping);
printf ("positive_sign: %s\n",lc->positive_sign);
printf ("negative_sign: %s\n",lc->negative_sign);
printf ("frac_digits: %d\n",lc->frac_digits);
printf ("p_cs_precedes: %d\n",lc->p_cs_precedes);
printf ("n_cs_precedes: %d\n",lc->n_cs_precedes);
printf ("p_sep_by_space: %d\n",lc->p_sep_by_space);
printf ("n_sep_by_space: %d\n",lc->n_sep_by_space);
printf ("p_sign_posn: %d\n",lc->p_sign_posn);
printf ("n_sign_posn: %d\n",lc->n_sign_posn);
printf ("int_frac_digits: %d\n",lc->int_frac_digits);
printf ("int_p_cs_precedes: %d\n",lc->int_p_cs_precedes);
printf ("int_n_cs_precedes: %d\n",lc->int_n_cs_precedes);
printf ("int_p_sep_by_space: %d\n",lc->int_p_sep_by_space);
printf ("int_n_sep_by_space: %d\n",lc->int_n_sep_by_space);
printf ("int_p_sign_posn: %d\n",lc->int_p_sign_posn);
printf ("int_n_sign_posn: %d\n",lc->int_n_sign_posn);

return 0;
}