C'est ce que j'ai proposé dans ma première réponse, mais on a eu le problème avec le locale... Il n'y a malhereusement pas de fonction qui passe comme ça un string en UpperCase :(
ceci-dit, si tu n'as pas été trop embrouillé par les réponses, tu auras compris que c'est simplement par-ce que le concept même d' "uppercase" d'une valeur n'a de sens que si l'on sait à quel caractère fait référence cette valeur (ie qu'on a la bonne locale).
Si tu imposes à l'appelant de se restreindre aux caractères encodables avec la locale C (qui est normalisée) et d'encoder les caractères de cette façon, c'est tout à fait possible et très simple.
-- Sam
le Tuesday 23 September 2003 16:34, cort@meloo.com écrivit :
C'est ce que j'ai proposé dans ma première réponse, mais on a eu le
problème avec le locale... Il n'y a malhereusement pas de fonction qui
passe comme ça un string en UpperCase :(
ceci-dit, si tu n'as pas été trop embrouillé par les réponses, tu auras
compris que c'est simplement par-ce que le concept même d' "uppercase"
d'une valeur n'a de sens que si l'on sait à quel caractère fait référence
cette valeur (ie qu'on a la bonne locale).
Si tu imposes à l'appelant de se restreindre aux caractères encodables avec
la locale C (qui est normalisée) et d'encoder les caractères de cette
façon, c'est tout à fait possible et très simple.
C'est ce que j'ai proposé dans ma première réponse, mais on a eu le problème avec le locale... Il n'y a malhereusement pas de fonction qui passe comme ça un string en UpperCase :(
ceci-dit, si tu n'as pas été trop embrouillé par les réponses, tu auras compris que c'est simplement par-ce que le concept même d' "uppercase" d'une valeur n'a de sens que si l'on sait à quel caractère fait référence cette valeur (ie qu'on a la bonne locale).
Si tu imposes à l'appelant de se restreindre aux caractères encodables avec la locale C (qui est normalisée) et d'encoder les caractères de cette façon, c'est tout à fait possible et très simple.
-- Sam
Samuel Krempp
le Tuesday 23 September 2003 17:06, écrivit :
Si tu imposes à l'appelant de se restreindre aux caractères encodables avec la locale C (qui est normalisée) et d'encoder les caractères de cette façon, c'est tout à fait possible et très simple.
tu peux d'ailleurs simplement imposer que la locale globale courante doit correspondre à l'encodage utiliser dans le string passé. puis utiliser les fonctions toupper de la locale en cours. C'est moins restreingant. et à priori c'est un comportement assez naturel dans une fonction à qui l'on ne précise pas de locale.
<locale> est expliqué par exemple dans l'appendix téléchargeable de stroustrup http://www.research.att.com/~bs/3rd_loc0.html
sur une plateforme ayant <locale>, on peut adatper le CMP_NoCase de Michaël :
le Tuesday 23 September 2003 17:06, krempp@crans.truc.en.trop.ens-cachan.fr
écrivit :
Si tu imposes à l'appelant de se restreindre aux caractères encodables
avec la locale C (qui est normalisée) et d'encoder les caractères de cette
façon, c'est tout à fait possible et très simple.
tu peux d'ailleurs simplement imposer que la locale globale courante doit
correspondre à l'encodage utiliser dans le string passé. puis utiliser les
fonctions toupper de la locale en cours. C'est moins restreingant.
et à priori c'est un comportement assez naturel dans une fonction à qui l'on
ne précise pas de locale.
<locale> est expliqué par exemple dans l'appendix téléchargeable de
stroustrup
http://www.research.att.com/~bs/3rd_loc0.html
sur une plateforme ayant <locale>, on peut adatper le CMP_NoCase de
Michaël :
Si tu imposes à l'appelant de se restreindre aux caractères encodables avec la locale C (qui est normalisée) et d'encoder les caractères de cette façon, c'est tout à fait possible et très simple.
tu peux d'ailleurs simplement imposer que la locale globale courante doit correspondre à l'encodage utiliser dans le string passé. puis utiliser les fonctions toupper de la locale en cours. C'est moins restreingant. et à priori c'est un comportement assez naturel dans une fonction à qui l'on ne précise pas de locale.
<locale> est expliqué par exemple dans l'appendix téléchargeable de stroustrup http://www.research.att.com/~bs/3rd_loc0.html
sur une plateforme ayant <locale>, on peut adatper le CMP_NoCase de Michaël :
"Michaël Monerau" wrote in message news:<QOYbb.58146$...
Fabien LE LEZ wrote:
On 21 Sep 2003 22:03:33 +0200, James Kanze wrote:
Au fait, existe-t-il des systèmes où les 52 lettres ([A-Za-z]) ne sont pas (toutes) présentes ?
Italien.
Je parlais de systèmes informatiques. Existe-t-il réellement un OS sur lequel les 52 lettres ne sont pas toutes présentes ? En d'autres termes, l'implémentation suivante a-t-elle un comportement défini ?
char Majuscule (char n) { if (n=='a') return 'A'; else if (n=='b') return 'B'; ... else if (n=='z') return 'Z'; else return n; }
Un switch n'est-il pas plus rapide ? (question dans l'absolu, pas seulement pour cette fonction d'exemple ;-) ).
La solution classique quand le problème est aussi simple, c'est un tableau :
char Majuscule( char n ) { return majToMin[ static_cast< unsigned char >( n ) ] ; }
L'avantage, évidemment, c'est que pour l'internationalisation, tu n'as que lire le tableau du disque, selon la locale.
Dans le cas de wchar_t (32 bits sur ma bécane), où le tableau risque être trop grand, j'utilise un hash_map dans mon implémentation.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
"Michaël Monerau" <cort@meloo.com> wrote in message
news:<QOYbb.58146$hd6.517080@news.chello.at>...
Fabien LE LEZ wrote:
On 21 Sep 2003 22:03:33 +0200, James Kanze <kanze@alex.gabi-soft.fr>
wrote:
Au fait, existe-t-il des systèmes où les 52 lettres ([A-Za-z]) ne
sont pas (toutes) présentes ?
Italien.
Je parlais de systèmes informatiques. Existe-t-il réellement un OS
sur lequel les 52 lettres ne sont pas toutes présentes ? En d'autres
termes, l'implémentation suivante a-t-elle un comportement défini ?
char Majuscule (char n)
{
if (n=='a') return 'A';
else if (n=='b') return 'B';
...
else if (n=='z') return 'Z';
else return n;
}
Un switch n'est-il pas plus rapide ? (question dans l'absolu, pas
seulement pour cette fonction d'exemple ;-) ).
La solution classique quand le problème est aussi simple, c'est un
tableau :
char Majuscule( char n )
{
return majToMin[ static_cast< unsigned char >( n ) ] ;
}
L'avantage, évidemment, c'est que pour l'internationalisation, tu n'as
que lire le tableau du disque, selon la locale.
Dans le cas de wchar_t (32 bits sur ma bécane), où le tableau risque
être trop grand, j'utilise un hash_map dans mon implémentation.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
"Michaël Monerau" wrote in message news:<QOYbb.58146$...
Fabien LE LEZ wrote:
On 21 Sep 2003 22:03:33 +0200, James Kanze wrote:
Au fait, existe-t-il des systèmes où les 52 lettres ([A-Za-z]) ne sont pas (toutes) présentes ?
Italien.
Je parlais de systèmes informatiques. Existe-t-il réellement un OS sur lequel les 52 lettres ne sont pas toutes présentes ? En d'autres termes, l'implémentation suivante a-t-elle un comportement défini ?
char Majuscule (char n) { if (n=='a') return 'A'; else if (n=='b') return 'B'; ... else if (n=='z') return 'Z'; else return n; }
Un switch n'est-il pas plus rapide ? (question dans l'absolu, pas seulement pour cette fonction d'exemple ;-) ).
La solution classique quand le problème est aussi simple, c'est un tableau :
char Majuscule( char n ) { return majToMin[ static_cast< unsigned char >( n ) ] ; }
L'avantage, évidemment, c'est que pour l'internationalisation, tu n'as que lire le tableau du disque, selon la locale.
Dans le cas de wchar_t (32 bits sur ma bécane), où le tableau risque être trop grand, j'utilise un hash_map dans mon implémentation.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
kanze
"Ignace" wrote in message news:<3f703935$0$27604$...
"Geoffroy Baud" a écrit dans le message de news: 3f6d7d45$0$10417$
existe-t-il dans les lib std du C++ un moyen pour comparer deux string, et que le test sois case insensitive ?
if ( "NAME" == "name" ) return TRUE;
Moi j'ai trouvé une solution très bête en java. Je ne sais pas si elle est valide en C++ : je fait subir le même changement de casse aux deux éléments du test.
Metalangage (prétentieux):
if (str1.toUpper()==str2.toUpper()) ...
Tiens. En Java, je me serais plutôt servi de java.lang.String.equalsIgnoreCase. Mais ça ne fait que cacher le problème.
Il doit bien y avoir des conversions dans la stl et les classes string non ? Comme ça, c'est le système qui se débrouille avec les locales.
Le problème, c'est qu'au fond, il n'y a pas de solution.
En allemand, par exemple, si j'ignore la case, je dois avoir "Fuß" = "FUSS". Ce que je ne sais pas faire en Java ; en C++, c'est précisement le but des facettes std::collate.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
"Ignace" <pasdadresse@tropspame.desole> wrote in message
news:<3f703935$0$27604$626a54ce@news.free.fr>...
"Geoffroy Baud" <geoffroy.baud@wanadoo.fr> a écrit dans le message de news:
3f6d7d45$0$10417$626a54ce@news.free.fr...
existe-t-il dans les lib std du C++ un moyen pour comparer deux
string, et que le test sois case insensitive ?
if ( "NAME" == "name" )
return TRUE;
Moi j'ai trouvé une solution très bête en java. Je ne sais pas si elle
est valide en C++ : je fait subir le même changement de casse aux deux
éléments du test.
Metalangage (prétentieux):
if (str1.toUpper()==str2.toUpper()) ...
Tiens. En Java, je me serais plutôt servi de
java.lang.String.equalsIgnoreCase. Mais ça ne fait que cacher le
problème.
Il doit bien y avoir des conversions dans la stl et les classes string
non ? Comme ça, c'est le système qui se débrouille avec les locales.
Le problème, c'est qu'au fond, il n'y a pas de solution.
En allemand, par exemple, si j'ignore la case, je dois avoir "Fuß" = "FUSS". Ce que je ne sais pas faire en Java ; en C++, c'est précisement
le but des facettes std::collate.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
"Ignace" wrote in message news:<3f703935$0$27604$...
"Geoffroy Baud" a écrit dans le message de news: 3f6d7d45$0$10417$
existe-t-il dans les lib std du C++ un moyen pour comparer deux string, et que le test sois case insensitive ?
if ( "NAME" == "name" ) return TRUE;
Moi j'ai trouvé une solution très bête en java. Je ne sais pas si elle est valide en C++ : je fait subir le même changement de casse aux deux éléments du test.
Metalangage (prétentieux):
if (str1.toUpper()==str2.toUpper()) ...
Tiens. En Java, je me serais plutôt servi de java.lang.String.equalsIgnoreCase. Mais ça ne fait que cacher le problème.
Il doit bien y avoir des conversions dans la stl et les classes string non ? Comme ça, c'est le système qui se débrouille avec les locales.
Le problème, c'est qu'au fond, il n'y a pas de solution.
En allemand, par exemple, si j'ignore la case, je dois avoir "Fuß" = "FUSS". Ce que je ne sais pas faire en Java ; en C++, c'est précisement le but des facettes std::collate.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Fabien LE LEZ
On Tue, 23 Sep 2003 14:31:12 GMT, "Michaël Monerau" wrote:
Un switch n'est-il pas plus rapide ?
Peut-être, mais je voulais une implémentation où il n'y ait pas de conversion (histoire de se concentrer sur le point qui m'intéressait).
-- Let's face it, boys: the Trash Heap _is_ all. -- the Trash Heap, Fraggle Rock, ep 1
Ah oui, d'accord... En fait, ça permet de contourner le problème du toupper du C... ben il vaut mieux utiliser les toupper C++ de toutes façon. effectivement,
ils ne posent pas les problèmes de conversion signée qu'a cette fonction héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C dans <string.h>, c'est std::toupper(*p1, std::locale()) Si on fournit une fonction de comparaison indépendante à la casse, autant prendre la locale en argument. (ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça correspond à : std::ctype<char> const& fac std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
-- Sam
le Tuesday 23 September 2003 21:15, cort@meloo.com écrivit :
Ou dans la dernière édition ;-) que j'ai la chance d'avoir ! Mais j'en
suis quelques 100 pages avant...
argh. moi j'ai la 3°, et je suis très reconnaissant à Bjarne de fournir ses
appendixes.
sur une plateforme ayant <locale>, on peut adatper le CMP_NoCase de
Michaël :
Ah oui, d'accord... En fait, ça permet de contourner le problème du
toupper du C...
ben il vaut mieux utiliser les toupper C++ de toutes façon. effectivement,
ils ne posent pas les problèmes de conversion signée qu'a cette fonction
héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C dans
<string.h>, c'est std::toupper(*p1, std::locale())
Si on fournit une fonction de comparaison indépendante à la casse, autant
prendre la locale en argument.
(ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à :
// fac == std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper (*p1);
si j'ai compris le toupper de string.h,
char c;
toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça
correspond à :
std::ctype<char> const& fac std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper(c)
Ah oui, d'accord... En fait, ça permet de contourner le problème du toupper du C... ben il vaut mieux utiliser les toupper C++ de toutes façon. effectivement,
ils ne posent pas les problèmes de conversion signée qu'a cette fonction héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C dans <string.h>, c'est std::toupper(*p1, std::locale()) Si on fournit une fonction de comparaison indépendante à la casse, autant prendre la locale en argument. (ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça correspond à : std::ctype<char> const& fac std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
-- Sam
Michaël Monerau
Samuel Krempp wrote:
le Tuesday 23 September 2003 21:15, écrivit :
Ou dans la dernière édition ;-) que j'ai la chance d'avoir ! Mais j'en suis quelques 100 pages avant...
argh. moi j'ai la 3°, et je suis très reconnaissant à Bjarne de fournir ses appendixes.
C'est vrai que c'est une très bonne idée.
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça correspond à : std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
Ok. Je verrai ça plus en détail quand j'aurai avancé dans la lecture ;-) -- <=- Michaël "Cortex" Monerau -=>
Samuel Krempp wrote:
le Tuesday 23 September 2003 21:15, cort@meloo.com écrivit :
Ou dans la dernière édition ;-) que j'ai la chance d'avoir ! Mais
j'en suis quelques 100 pages avant...
argh. moi j'ai la 3°, et je suis très reconnaissant à Bjarne de
fournir ses appendixes.
C'est vrai que c'est une très bonne idée.
En fait, le toupper du C correspondrait à :
// fac == std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper (*p1);
si j'ai compris le toupper de string.h,
char c;
toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça
correspond à :
std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper(c)
Ok. Je verrai ça plus en détail quand j'aurai avancé dans la lecture ;-)
--
<=- Michaël "Cortex" Monerau -=>
Ou dans la dernière édition ;-) que j'ai la chance d'avoir ! Mais j'en suis quelques 100 pages avant...
argh. moi j'ai la 3°, et je suis très reconnaissant à Bjarne de fournir ses appendixes.
C'est vrai que c'est une très bonne idée.
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned je crois que ouais, ça correspond à : std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
Ok. Je verrai ça plus en détail quand j'aurai avancé dans la lecture ;-) -- <=- Michaël "Cortex" Monerau -=>
kanze
Samuel Krempp wrote in message news:<3f70bbc1$0$2790$...
le Tuesday 23 September 2003 21:15, écrivit :
[...]
Ah oui, d'accord... En fait, ça permet de contourner le problème du toupper du C...
ben il vaut mieux utiliser les toupper C++ de toutes façon. effectivement, ils ne posent pas les problèmes de conversion signée qu'a cette fonction héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C dans <string.h>, c'est std::toupper(*p1, std::locale())
C'est la plus simple, mais ça risque d'être lent -- on va appeler use_facet pour chaque caractère.
Si on fournit une fonction de comparaison indépendante à la casse, autant prendre la locale en argument.
(ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
Pas tout à fait. Le toupper de C dépend également du locale. Le locale global C établi par setlocale.
Le locale global de C et le locale global de C++ ne sont pas forcement les même.
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned
En unsigned char.
je crois que ouais, ça correspond à : std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
Non. Le toupper de C dépend du locale positionné par les appels à setlocale.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Samuel Krempp <krempp@crans.truc.en.trop.ens-cachan.fr> wrote in message
news:<3f70bbc1$0$2790$626a54ce@news.free.fr>...
le Tuesday 23 September 2003 21:15, cort@meloo.com écrivit :
[...]
Ah oui, d'accord... En fait, ça permet de contourner le problème du
toupper du C...
ben il vaut mieux utiliser les toupper C++ de toutes façon.
effectivement, ils ne posent pas les problèmes de conversion signée
qu'a cette fonction héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C
dans <string.h>, c'est std::toupper(*p1, std::locale())
C'est la plus simple, mais ça risque d'être lent -- on va appeler
use_facet pour chaque caractère.
Si on fournit une fonction de comparaison indépendante à la casse,
autant prendre la locale en argument.
(ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à :
// fac == std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper (*p1);
Pas tout à fait. Le toupper de C dépend également du locale. Le locale
global C établi par setlocale.
Le locale global de C et le locale global de C++ ne sont pas forcement
les même.
si j'ai compris le toupper de string.h,
char c;
toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned
En unsigned char.
je crois que ouais, ça
correspond à :
std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C"))
fac.toupper(c)
Non. Le toupper de C dépend du locale positionné par les appels à
setlocale.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
Samuel Krempp wrote in message news:<3f70bbc1$0$2790$...
le Tuesday 23 September 2003 21:15, écrivit :
[...]
Ah oui, d'accord... En fait, ça permet de contourner le problème du toupper du C...
ben il vaut mieux utiliser les toupper C++ de toutes façon. effectivement, ils ne posent pas les problèmes de conversion signée qu'a cette fonction héritée du C.
la plus simple façon d'utiliser std::toupper pour remplacer celui du C dans <string.h>, c'est std::toupper(*p1, std::locale())
C'est la plus simple, mais ça risque d'être lent -- on va appeler use_facet pour chaque caractère.
Si on fournit une fonction de comparaison indépendante à la casse, autant prendre la locale en argument.
(ah là j'ai mis la facet en argument, sans raison particulière)
En fait, le toupper du C correspondrait à : // fac == std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper (*p1);
Pas tout à fait. Le toupper de C dépend également du locale. Le locale global C établi par setlocale.
Le locale global de C et le locale global de C++ ne sont pas forcement les même.
si j'ai compris le toupper de string.h, char c; toupper(c) == toupper( (int) c) // oops ?
mais si on transforme d'abord c en unsigned
En unsigned char.
je crois que ouais, ça correspond à : std::ctype<char> const& fac > std::use_facet<std::ctype<char> >(std::locale("C")) fac.toupper(c)
Non. Le toupper de C dépend du locale positionné par les appels à setlocale.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16