[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 594.   C: «locale.h»

Il file locale.h della libreria standard definisce delle macro-variabili, un tipo di struttura e alcune funzioni, relative alla gestione della configurazione locale del programma. Se non si fa uso di tale configurazione, il proprio programma opera in quella che è nota come «configurazione locale C», ovvero il minimo indispensabile.

Nell'ambito di un sistema operativo Unix o simile, la configurazione locale avviene principalmente attraverso l'impostazione di variabili di ambiente il cui nome inizia per LC_.... Tuttavia, questa configurazione non viene ereditata automaticamente dal programma scritto in linguaggio C, perché questo deve acquisirla espressamente, se vuole.

La definizione della configurazione locale avviene attraverso una stringa contenente delle sigle che esprimono la lingua, la nazionalità e la codifica da utilizzare per rappresentare i caratteri. Per esempio, it_CH.UTF-8 rappresenta la lingua italiana, la nazionalità svizzera e la codifica UTF-8.

594.1   Impostazione della configurazione locale

Per modificare l'impostazione della configurazione locale del proprio programma, si utilizza la funzione setlocale() che richiede l'indicazione di un numero intero, a indicare la categoria nella quale intervenire. La categoria viene definita formalmente attraverso delle macro-variabili il cui nome inizia per LC_... e si tratta degli stessi nomi usati nelle variabili di ambiente di un sistema Unix o simile. Viene proposto un esempio di dichiarazione delle macro-variabili indispensabili, ma l'associazione al numero varia molto da un sistema all'altro:

LC_ALL          0
LC_COLLATE      1
LC_CTYPE        2
LC_MONETARY     3
LC_NUMERIC      4
LC_TIME         5

La funzione setlocale() con cui si cambia la configurazione locale ha il prototipo seguente:

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

Si prevedono due situazioni diverse di utilizzo della funzione. Per cominciare può essere usata per interrogare la configurazione attuale, come nell'esempio seguente:

...
char *p;
p = setlocale (LC_COLLATE, NULL);
...

Fornendo un puntatore nullo, al posto della stringa che deve indicare la configurazione locale, si ottiene un puntatore alla stringa che descrive quella attuale. In questo caso, se si utilizza la categoria LC_ALL, si ottiene una stringa che descrive tutte le altre categorie, ammesso che ci siano delle differenze. Se invece la funzione non è in grado di dare questa informazione, si ottiene semplicemente un puntatore nullo.

Naturalmente, la funzione serve anche per cambiare la configurazione locale, specificando in tal caso la stringa che la descrive. Per esempio, nel modo seguente si interviene nella categoria LC_NUMERIC:

...
char *p;
p = setlocale (LC_NUMERIC, "it_IT.UTF-8");
...

Anche in questo caso si ottiene un puntatore che descrive la categoria scelta, ma se l'operazione fallisce, si ottiene invece il puntatore nullo.

Normalmente è più probabile che, nell'impostazione della configurazione locale si voglia indicare una modalità unica per tutte le categorie; pertanto, in tal caso va usato LC_ALL:

...
p = setlocale (LC_ALL, "it_IT.UTF-8");
...

Viene mostrato un esempio di programma completo, in cui si imposta prima la configurazione locale complessiva, poi se ne cambia una e quindi si interroga la situazione:

#include <stdio.h>
#include <locale.h>

int main (void)
{
    setlocale (LC_ALL, "it_IT.UTF-8");
    setlocale (LC_MONETARY, "en_US.UTF-8");

    printf ("LC_COLLATE:  \"%s\"\n", setlocale (LC_COLLATE, NULL));
    printf ("LC_CTYPE:    \"%s\"\n", setlocale (LC_CTYPE, NULL));
    printf ("LC_MONETARY: \"%s\"\n", setlocale (LC_MONETARY, NULL));
    printf ("LC_NUMERIC:  \"%s\"\n", setlocale (LC_NUMERIC, NULL));
    printf ("LC_TIME:     \"%s\"\n", setlocale (LC_TIME, NULL));
    printf ("LC_ALL:      \"%s\"\n", setlocale (LC_ALL, NULL));

    return 0;
}

Ecco cosa si può ottenere:

LC_COLLATE:  "it_IT.UTF-8"
LC_CTYPE:    "it_IT.UTF-8"
LC_MONETARY: "en_US.UTF-8"
LC_NUMERIC:  "it_IT.UTF-8"
LC_TIME:     "it_IT.UTF-8"
LC_ALL:      "LC_CTYPE=it_IT.UTF-8;LC_NUMERIC=it_IT.UTF-8;\
  \LC_TIME=it_IT.UTF-8;LC_COLLATE=it_IT.UTF-8;LC_MONETARY=en_US.UTF-8"

Per fare sì che il programma erediti la configurazione locale dal contesto in cui si trova a funzionare (quindi dalla configurazione locale del sistema operativo), si può indicare la stringa nulla al posto della definizione:

:-)

...
p = setlocale (LC_ALL, "");
...

Pertanto, questo è il modo appropriato per iniziare la configurazione all'interno di un programma.

594.2   Composizione dei valori numerici

Il modo in cui si rappresenta un valore numerico, con o senza indicazione della valuta (la moneta), dipende dalla configurazione locale. La funzione localeconv() restituisce il puntatore a una struttura che contiene i dettagli riguardo alle modalità di rappresentazione dei valori numerici, secondo la configurazione locale. L'utilizzo consentito di questa struttura si limita all'interrogazione dei valori, perché la modifica dipende dalla gestione della configurazione locale.

struct lconv {char *decimal_point;
              char *thousands_sep;
              char *grouping;
              char *mon_decimal_point;
              char *mon_thousands_sep;
              char *mon_grouping;
              char *positive_sign;
              char *negative_sign;
              char *currency_symbol;
              char frac_digits;
              char p_cs_precedes;
              char n_cs_precedes;
              char p_sep_by_space;
              char n_sep_by_space;
              char p_sign_posn;
              char n_sign_posn;
              char *int_curr_symbol;
              char int_frac_digits;
              char int_p_cs_precedes;
              char int_n_cs_precedes;
              char int_p_sep_by_space;
              char int_n_sep_by_space;
              char int_p_sign_posn;
              char int_n_sign_posn;
};

A titolo di esempio vengono descritti solo alcuni membri della struttura; per gli altri ci si deve consultare la documentazione dello standard:

Membro Descrizione
decimal_point
Stringa contenente il carattere usato per separare la parte decimale in un numero per uso generale.
thousand_sep
Stringa contenente il carattere usato per separare le cifre della parte intera di un numero per uso generale.
positive_sign
negative_sign
Stringa contenente il carattere usato per rappresentare il segno, positivo o negativo, di un numero usato per le valute.
int_curr_symbol
Stringa composta da quattro caratteri, di cui i primi tre indicano la sigla internazionale della valuta (USD, EUR, ecc.) e il quarto è solo un carattere di separazione da usare tra tale sigla e il valore numerico a cui questa si riferisce.

I membri che rappresentano delle stringhe (puntatori a carattere), quando si riferiscono a dati facoltativi, possono essere vuoti (nel senso di stringhe nulle). I membri di tipo char vengono usati in modo numerico.

struct lconv *localeconv (void);

Come si vede dal prototipo, la funzione localeconv() serve esclusivamente per ottenere il puntatore alla struttura lconv, da usare per la sua consultazione. Viene mostrato un esempio molto semplice per il suo utilizzo:

#include <stdio.h>
#include <locale.h>

int main (void)
{
    struct lconv *lc;

    setlocale (LC_ALL, "it_IT.UTF-8");
    lc = localeconv ();

    printf ("decimal_point:\t\t\"%s\"\n", lc->decimal_point);
    printf ("thousand_sep:\t\t\"%s\"\n", lc->thousands_sep);
    printf ("grouping:\t\t\"%s\"\n", lc->grouping);
    printf ("mon_decimal_point:\t\"%s\"\n", lc->mon_decimal_point);
    printf ("mon_thousands_sep:\t\"%s\"\n", lc->mon_thousands_sep);
    printf ("mon_grouping:\t\t\"%s\"\n", lc->mon_grouping);
    printf ("positive_sign:\t\t\"%s\"\n", lc->positive_sign);
    printf ("negative_sign:\t\t\"%s\"\n", lc->negative_sign);
    printf ("currency_symbol:\t\"%s\"\n", lc->currency_symbol);  // Multibyte.
    printf ("frac_digits:\t\t%d\n", lc->frac_digits);
    printf ("p_cs_precedes:\t\t%d\n", lc->p_cs_precedes);
    printf ("n_cs_precedes:\t\t%d\n", lc->n_cs_precedes);
    printf ("p_sep_by_space:\t\t%d\n", lc->p_sep_by_space);
    printf ("n_sep_by_space:\t\t%d\n", lc->n_sep_by_space);
    printf ("p_sign_posn:\t\t%d\n", lc->p_sign_posn);
    printf ("n_sign_posn:\t\t%d\n", lc->n_sign_posn);
    printf ("int_curr_symbol:\t\"%s\"\n", lc->int_curr_symbol);
    printf ("int_frac_digit:\t\t%d\n", lc->int_frac_digit);
    printf ("int_p_cs_precedes:\t\t%d\n", lc->int_p_cs_precedes);
    printf ("int_n_cs_precedes:\t\t%d\n", lc->int_n_cs_precedes);
    printf ("int_p_sep_by_space:\t\t%d\n", lc->int_p_sep_by_space);
    printf ("int_n_sep_by_space:\t\t%d\n", lc->int_n_sep_by_space);
    printf ("int_p_sign_posn:\t\t%d\n", lc->int_p_sign_posn);
    printf ("int_n_sign_posn:\t\t%d\n", lc->int_n_sign_posn);

    return 0;
}

Il risultato che si ottiene dovrebbe essere molto simile a quello seguente:

decimal_point:          ","
thousand_sep:           ""
grouping:               ""
mon_decimal_point:      ","
mon_thousands_sep:      "."
mon_grouping:           ""
positive_sign:          ""
negative_sign:          "-"
currency_symbol:        "€"
frac_digits:            2
p_cs_precedes:          1
n_cs_precedes:          1
p_sep_by_space:         1
n_sep_by_space:         1
p_sign_posn:            1
n_sign_posn:            1
int_curr_symbol:        "EUR "
int_frac_digit:         2
int_p_cs_precedes:      1
int_n_cs_precedes:      1
int_p_sep_by_space:     1
int_n_sep_by_space:     1
int_p_sign_posn:        1
int_n_sign_posn:        4

Si osservi che, nell'esempio, la stringa a cui si accede tramite il membro currency_symbol è una sequenza «multibyte», nel senso che utilizza più byte per rappresentare un solo carattere.

594.3   Riferimenti


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome c_171_locale_h_187.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory