Site Tools


wiki:locale.h

Table of Contents

locale.h

locale.h controls how your program formats and interprets culture-specific data: whether the decimal separator is . or ,, what the currency symbol is, which characters count as letters. By default a C program runs in the "C" locale — ASCII, . decimal separator, no localisation — which is predictable but not what a German or French user expects to see.

#include <locale.h>
 
setlocale(LC_ALL, "");              // pick up the user's environment locale
setlocale(LC_ALL, "C");             // reset to the predictable ASCII baseline
setlocale(LC_NUMERIC, "de_DE.UTF-8");  // German number format only

The category lets you change one aspect without touching the others:

Category Controls
LC_ALL Everything
LC_NUMERIC Decimal point, thousands separator
LC_MONETARY Currency symbol and format
LC_CTYPE isalpha, toupper etc.
LC_COLLATE String comparison order
LC_TIME strftime output

localeconv() returns a struct lconv with all the current locale's formatting strings: decimal_point, thousands_sep, currency_symbol, and more.

The practical rule: call setlocale(LC_ALL, "") at startup if you are producing output for humans. But be careful with LC_NUMERIC — any library that calls setlocale on your behalf can change the decimal separator under your feet, which will break strtod parsing of machine-generated data. Keep LC_NUMERIC as "C" when parsing programmatic input.

Practice

// compile: gcc -o localedemo localedemo.c
// run: ./localedemo
// description: show how locale changes decimal formatting; install de_DE if missing
 
#include <locale.h>
#include <stdio.h>
 
int main(void) {
    double pi = 3.141592653589793;
 
    setlocale(LC_ALL, "C");
    printf("C locale:      %f\n", pi);   // 3.141593
 
    if (!setlocale(LC_NUMERIC, "de_DE.UTF-8") &&
        !setlocale(LC_NUMERIC, "de_DE"))
        puts("de_DE locale not available; install with: sudo locale-gen de_DE.UTF-8");
    else {
        printf("de_DE locale:  %f\n", pi);   // 3,141593 (comma!)
        printf("decimal_point = '%s'\n", localeconv()->decimal_point);
    }
    return 0;
}

If the German locale is installed you will see a comma instead of a dot in the second line. If not, install it with sudo locale-gen de_DE.UTF-8 on Debian/Ubuntu. Once you have seen this in action it is hard to forget that LC_NUMERIC can silently change how printf and strtod work.

wiki/locale.h.md · Last modified: by 127.0.0.1