Swisslinux.org

− Le carrefour GNU/Linux en Suisse −

 

Langue

 

Le Forum

Vous n'êtes pas identifié.

#1 16 Jul 2009 10:16:16

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

[C] setlocale() et les threads (Résolu)

Hi,

j'ai un problème un peu particulier avec une bibliothèque. Celle-ci fait du parsing via des fonctions tel que atof(), sscanf(), ... et il y a donc des champs à analyser qui ressemblent à FOO=1.2345.
Le problème apparait quand le programme qui utilise cette bibliothèque change de locale. Le programme est internationalisé. Du coup la bibliothèque prend une nouvelle locale et atof() "dans le cas des français" cherche une virgule à la place d'un point pour la séparation des décimales. Le champ FOO=1.2345 est donc compris bêtement en FOO=1,0 vu que atof() ne comprend plus ce qu'est le point.

Une première solution serait de réécrire des fonctions my_atof(), my_sscanf() qui rechangeraient la locale en "C". Mais la bibliothèque étant multi-threads, il n'y a aucun garantie que le programme principal fasse pas quelque chose qui demanderait la locale précédente en même temps.

Il me faut donc pouvoir changer la locale que pour le thread.


Merci pour toutes aides éventuelles.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#2 16 Jul 2009 11:44:33

lochost
Citoyen(ne)
Lieu: Genève
Date d'inscription: 12 Jun 2009
Messages: 19

Re: [C] setlocale() et les threads (Résolu)

Idée "juste comme ça en passant" :

créer une fonction qui ne fait rien d'autre que de transformer le point en virgule avant de passer le paramètre à la fonction originale; ça t'éviterai de devoir jongler avec les locale.

Je ne sais pas si c'est une bonne idée, ne connaissant rien de rien à la prog multi-thread, mais c'est ce que je tenterais.

En espérant t'avoir été utile (ce dont je doute un peu, mais bon roll)

L.


-----BEGIN GEEK CODE BLOCK-----
Version: 3.1 GCS/IT$/L d- s: a C++ UL P L++ E-- W+ N o? K? w$ O? M V?
PS PE? Y+ PGP t- 5? X R+ tv b++ DI D- G e+ h-- r++ y+
------END GEEK CODE BLOCK------

Hors ligne

 

#3 16 Jul 2009 15:21:37

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] setlocale() et les threads (Résolu)

ça implique de savoir exactement ce que font toutes les locales..  en fonction de toutes les langues du monde et donc de leurs spécificités.. peut être bien qu'il n'y a que le point et la virgule qui poseront un problème.. mais peut être pas, je n'ai pas de garanti..

En changeant la locale uniquement pour le thread j'ai pas besoin de me poser la moindre question sur ce qui est utilisé par le système en amont.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#4 16 Jul 2009 16:08:55

lochost
Citoyen(ne)
Lieu: Genève
Date d'inscription: 12 Jun 2009
Messages: 19

Re: [C] setlocale() et les threads (Résolu)

Petite googlization rapide avec "séparateur décimal" et je suis tombé là-dessus (ouille!) http://fr.wikipedia.org/wiki/S%C3%A9par … C3%A9cimal

...si j'ai tout bien compris il n'y aurait, en gros, que trois sortes de séparateurs décimaux : le point, la virgule et le "momayyez" : une sorte de slash utilisé dans les pays arabes.

Donc, si tu trouves pas d'autre solution, tu pourrais te référer à la soluce proposée à ceci près : elle devrait convertir tout ce qui n'est pas un chiffre en un point.

Acceptable (même comme pis-aller) ?

L.


-----BEGIN GEEK CODE BLOCK-----
Version: 3.1 GCS/IT$/L d- s: a C++ UL P L++ E-- W+ N o? K? w$ O? M V?
PS PE? Y+ PGP t- 5? X R+ tv b++ DI D- G e+ h-- r++ y+
------END GEEK CODE BLOCK------

Hors ligne

 

#5 16 Jul 2009 17:09:06

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] setlocale() et les threads (Résolu)

lochost a écrit:

Donc, si tu trouves pas d'autre solution, tu pourrais te référer à la soluce proposée à ceci près : elle devrait convertir tout ce qui n'est pas un chiffre en un point.

L'inverse plutôt, car atof() va s'attendre à trouver parfois un point, parfois une virgule et parfois le symbole arabe. Donc le point doit être converti en fonction de la locale. Merci pour ton aide, je vais qu'en même continuer à chercher pour pouvoir forcer la locale par défaut. Autrement c'est un piège à bug à la moindre utilisation de fonctions de string.


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#6 16 Jul 2009 19:47:55

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] setlocale() et les threads (Résolu)

Bien que j'avais regardé l'header locale, j'étais passé à côté d'une extension du GNU:

Code:

195 /* Switch the current thread's locale to DATASET.
196    If DATASET is null, instead just return the current setting.
197    The special value LC_GLOBAL_LOCALE is the initial setting
198    for all threads and can also be installed any time, meaning
199    the thread uses the global settings controlled by `setlocale'.  */
200 extern __locale_t uselocale (__locale_t __dataset) __THROW;

Ça devrait me permettre de régler le problème proprement.

EDIT:
Ainsi ça fonctionne:

Code:

#define _GNU_SOURCE
#include <locale.h>
#include <stdlib.h>

double
my_atof (const char *nptr)
{
  double res;
  locale_t new_locale, prev_locale;
 
  new_locale = newlocale (LC_NUMERIC_MASK, "C", NULL);
  prev_locale = uselocale (new_locale);
  res = atof (nptr);
  uselocale (prev_locale);
  freelocale (new_locale);
 
  return res;
}

Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#7 17 Jul 2009 16:33:39

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] setlocale() et les threads (Résolu)

Une autre variante qui évite atof() et uselocale(), et qui est donc plus simple (la valeur de retour peut "échouer" avec HUGE_VAL contrairement à atof()):

Code:

#define _GNU_SOURCE
#include <locale.h>
#include <stdlib.h>

double
my_atof (const char *nptr)
{
  double res;
  locale_t new_locale;

  new_locale = newlocale (LC_NUMERIC_MASK, "C", NULL);
  res = strtod_l (nptr, NULL, new_locale);
  freelocale (new_locale);

  return res;
}

Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

Pied de page des forums

Powered by FluxBB