Newsgroup: it.comp.os.linux.development
Titolo: [Bug ?] Problemi con il separatore decimale in C/C++ e Perl

Ciao,
uso le librerie glibc-devel-2.3.3-20mdk della Mandrake 10.1, ma il
problema si presenta anche con le librerie della Suse 9.2 e 9.3, con le
librerie di default delle altre distro non ho provato.
    Sviluppando programmi in Perl ed in C/C++ mi sono accorto che, pur
avendo settato correttamente le impostazioni locali italiane, i calcoli
aritmetici nei programmi vengono fatti usando come separatore decimale
il punto invece che la virgola.
Esempio:
#include <stdio.h>
#include <locale.h>
int main()
{
float d,g;
setlocale(LC_ALL,"it_IT"); //provato anche con tutte le possibilità
date dal comando
                                      // locale -a. Ovvero
"it_IT.UTF-8", "it_IT.ISO-8859-15", ecc.
g=0,2;    // N.B. Uso la virgola come separatore decimale
d=g*10;
printf("g=%f; d=%f; \n",g,d);     // Da questa si ottiene:  g=0,000000;
d=0,000000;
                                           // LA VIRGOLA NON VIENE
RICONOSCIUTA COME
                                           //SEPARATORE DECIMALE NEI
CONTI, MA SOLO
                                           //NEL FORMATO DI STAMPA
//INVECE
g=0.2;  //N.B Uso il punto come separatore decimale
d=g*10;
printf("g=%f; d=%f; \n",g,d);    // Da questa si ottiene: g=0,200000;
d=2,000000;
//MA LA COSA PIÙ PREOCCUPANTE È
struct lconv convenzioni_locali;
convenzioni_locali=*localeconv(); // Assegna allo struct tutte le
impostazioni locali
char cd;
cd=*(convenzioni_locali.decimal_point);
printf("%c \n",cd); // Da questa si orriene stampata la virgola come
dovrebbe essere.
}
Questo accade anche dopo aver dato il comando:
$ export LC_ALL=it_IT.UTF-8  //ma anche con it_IT, oppure con
it_IT.ISO-8859-15, ecc..
Eseguendo il comando: $ locale
ottengo correttamente, fra le altre, la stringa:
LC_NUMERIC="it_IT.UTF-8", oppure quella che ho impostato con il comando
di cui sopra.
L'unica cosa che ho notato è che se si esegue il comando $ locale
prima di aver dato il comando $ export LC_ALL=it_IT.UTF-8, si ottengono
le stringhe senza virgolette, tipo:
LC_NUMERIC=it_IT.UTF-8, mentre se si esegue dopo l'export si avrà:
LC_NUMERIC="it_IT.UTF-8".
Per quanto riguarda il Perl si ottiene la stessa cosa, ma credo che
dipenda dalle librerie c di sistema.
Credo di aver letto da qualche parte che può essere necessario
ricompilare le librerie c.
In questa ipotesi qualcuno saprebbe dirmi come si esegue correttamente
questa operazione, tenendo conto delle impostazioni locali?
Vi ringrazio anticipatamente per i suggerimenti.

 
 
Il 'locale' riguarda le funzioni di output e input.
Il formato che usi nel sorgente dipende dalle regole sintattiche del 
linguaggio, e quelle, naturalmente, non cambiano.
In C/C++ e in Perl, la virgola ha un altro significato.
Max

Max M. ha scritto:

Grazie Max, ma il problema è che io in Perl avevo già scritto
parecchio codice usando le seguenti istruzioni:
use POSIX qw(locale_h);
use locale;
setlocale(LC_ALL,"italian");
......
e tutto funzionava a meraviglia, cioè riuscivo ad avere input/output
in formato corretto ed inoltre a fare i conti senza dover passare dal
punto alla virgola e viceversa nelle variabili.
Questo avveniva con le librerie ed i settaggi di default delle release
della Mandrake precedenti la 10.0.
Con la 10.1 lo stesso codice mi sbagliava i conti. Ma lo stesso
accadeva con altre due distro della Suse. Con le altre non ho provato.
Andando a verificare ho potuto notare che tutto dipendeva dalle
librerie del C.
Lo scopo di questo post è anche quello di chiedere se altri hanno il
mio stesso problema e di avvertire su una potenziale fonte di errore
nei programmi.
      Se poi fosse possibile sarebbe bello avere anche una soluzione.
Grazie a tutti per l'attenzione.

 punto alla virgola e viceversa nelle variabili.
Ma tu parlavi della 'virgola' nel *codice*, mentre qui parli di
input/output. O vuoi dire che in Perl usavi ',' come separatore dei
decimali direttamente nel codice?
Max

Ho usato la virgola come separatore decimale direttamente nel codice
perl.
Inoltre avevo ben presente il problema del separatore decimale ed ho
verificato che usando le istruzioni:
 use POSIX qw(locale_h);
 use locale;
 setlocale(LC_ALL,"italian");
ottenevo il comportamento corretto, cioè la parte dopo la virgola era
riconosciuta come parte decimale nei conti.
Potrebbe anche essere che questo dipendeva da qualche particolare
configurazione della mia installazione del perl, o da altro.
Prima di sollevare più seriamente la questione, riinstallerò qualche
distribuzione sulla quale mi sembrava che tutto funzionasse bene e poi
ti farò sapere.
Gianni