[Hackmeeting] ABSURD localization of the radix character in …

Nachricht löschen

Nachricht beantworten
Autor: marc0@autistici.org
Datum:  
Betreff: [Hackmeeting] ABSURD localization of the radix character in libc !!!!
jaromil on Fri, 12 Nov 2004 02:14:22 +0100 writes:

> a me pare che potrebbe essere scritto qualcosa di MOLTO piu' semplice
> per parsare stringhe<->numeri con virgola mobile, no?


questo non lo so, comunque

IMHO la libc non e' sbagliata: quando la imposti per
leggere/scrivere rappresentazioni di numeri in italiano, le
legge/scrive in italiano (con la `,' a dividere le unita' dai
decimali), quando la imposti per leggerle/scriverle in inglese, le
legge/scrive in inglese, e cosi' via.

il problema e' quando viene impostata per leggerle in un locale (ad
esempio italiano) ma le vengono dati in input rappresentazioni di
numeri in un altro locale (ad esempio "C").

la soluzione e' che la libc _deve_ sapere in che locale e' scritto il numero.

IMHO quelli di GTK con `g_strtod' non hanno fatto la cosa giusta: la
rappresentazione di un numero (ad esempio "1,000") e' fatta per
contenere il numero, non per indicare in che locale (lingua) e',
quindi determinare quest'ultima informazione dalla rappr. del numero
e' un po' un wokaround, non una correzione. magari l'hanno fatto con
lo scopo di toppare buchi di altro codice, ma rimane un solo workaround.

comunque IMHO:

  - o nel tuo programma gestisci tutte le rappr. di numeri localizzate
    (ad esempio in italiano), e carichi quindi anche la sezione
    LC_NUMERIC del locale. questo non sempre e' possibile.


  - o le gestisci tutte nel locale "C", e quindi fai in modo di non
    caricare la sezione LC_NUMERIC del locale. questa e' la cosa piu'
    semplice: tutti scrivono e leggono i numeri in inglese e bom.


  - o fai in modo di sapere dove ti servono localizzate (ad esempio
    input utente), e dove no (ad esempio per caricare/salvare file)


    questo come? o come hanno fatto quelli di GTK con
    `g_ascii_strtod', cioe' ti reimplementi un parser che non sia
    localizzato, e usi quello dove non ti serve la localizzazione, o
    se puoi dipendere dalla GNU LibC puoi utilizzare quelle
    implementate dalla GNU LibC:


      __strtod_l
      __strtof_l
      __strtold_l


che comunque nella documentazione, anche se scritto in piccolo, ci
sono, quindi non sono poi tanto interne quindi mi aspetterei un
minimo di stabilita' (cioe' che ci saranno ancora in versioni future):

(info "(libc) Parsing of Floats") :

   << The GNU C library also provides `_l' versions of these functions,
     which take an additional argument, the locale to use in conversion.>>


/* lcl.c */
#include <libintl.h>
#include <xlocale.h>
#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define PACKAGE "test"
#define LOCALEDIR "/usr/share/locale"

int main()
{
        char a[1000] = "1.234";
    char b[1000];
        float f;
    __locale_t defaultloc = __newlocale(LC_ALL, "C", NULL);
        bindtextdomain (PACKAGE, LOCALEDIR);
        textdomain (PACKAGE);
        setlocale (LC_ALL, "");
    f = __strtof_l (a, NULL, defaultloc);
        printf("read [C]: %s -> %f\n>", a, f);
    scanf ("%s", &b);
    f = strtof (b, NULL);
        printf("read [localized]: %s -> %f\n", b, f);
}
/* fine lcl.c */


$ gcc -D_GNU_SOURCE -o lcl lcl.c
$ export LANG=it_IT
$ ./lcl
read [C]: 1.234 -> 1,234000
>1,22

read [localized]: 1,22 -> 1,220000
$ export LANG=C
$ ./lcl
read [C]: 1.234 -> 1.234000
>1.22

read [localized]: 1.22 -> 1.220000
$

ciao

--
<marc0@???> [0x45070AD6]