Gestion des caractères internationaux

Le
Michel Pitermann
Bonjour,

Ce code :

************************************************************

#include <iostream>

int main()
{
wchar_t c;
while (std::wcin >> c) std::wcout << c;

return 0;
}

*************************************************************

ne fonctionne pas sur Ubuntu Lucid avec g++ 4.4.3 et un noyau
2.6.32-25-server. Le programme a été compilé sans options (g++
aa.cc). Le programme arrête la lecture de l'entrée standard sur le
premier caractère non ascii. Par exemple, donner "azertéqsdfg" ne
traitera que "azert" et s'arretera sur "é". Mon environnement est
intégralement initialisé en UTF-8. Est-ce normal ?
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #22634371
In article Michel Pitermann
Bonjour,

Ce code :

************************************************************

#include <iostream>

int main()
{
wchar_t c;
while (std::wcin >> c) std::wcout << c;

return 0;
}

*************************************************************

ne fonctionne pas sur Ubuntu Lucid avec g++ 4.4.3 et un noyau
2.6.32-25-server.



Au moins en C, il faut un setlocale(""); pour passer dans "la locale par
defaut". Un programme demarre avec la locale "C" pour de betes raisons de
securite (histoire de pouvoir avoir un comportement reproductible
independamment de l'environnement de l'utilisateur).

Je ne suis pas pratiquant regulier des facets du C++ standard, donc c'est
peut-etre completement autre chose, mais ca me parait coherent avec ce
que tu observes.
Michel Pitermann
Le #22634421
Au moins en C, il faut un setlocale(""); pour passer dans "la locale par



Merci pour l'info. J'ai eu le même résultat avec la version suivante :

*************************************************************
#include <iostream>
#include <locale>


int main()
{
// std::locale loc("fr_FR.utf8");
std::locale loc("");
std::cout.imbue(loc);
std::wcout.imbue(loc);
std::cin.imbue(loc);
std::wcin.imbue(loc);

wchar_t c;
while (std::wcin >> c) std::wcout << c;

return 0;
}
***************************************************************
J'ai essayé avec les 2 arguments pour "locale", celui en commentaire
et le programme compilé tel quel. Je n'ai toujours rien trouvé d'autre
dans le web.
Jean-Marc Bourguet
Le #22634531
Michel Pitermann
#include <iostream>

int main()
{
wchar_t c;
while (std::wcin >> c) std::wcout << c;

return 0;
}



#include <iostream>
#include <locale>

int main()
{
wchar_t c;
std::locale::global(std::locale(""));
while (std::wcin >> c)
std::wcout << c;

return 0;
}

fonctionne chez moi, dans quasiment les mêmes conditions.

A+

--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Michel Pitermann
Le #22634651
fonctionne chez moi, dans quasiment les mêmes conditions.



Chez moi aussi :-) Mille mercis. Il s'agit visiblement de la gestion
de "locale" que je ne maîtrise pas assez bien. Je ne comprends pas ce
que Stroustrup voulait dire dans « The C programming language, third
edition » page 650 :

"Setting the global locale does not change the behavior of existing
streams that are using the previous value of the global locale. In
particular, cin, cout, etc., are not affected. If they should be
changed, they must be explicitly imbue()d."

On dirait que gcc fait le contraire. Je venais de commencer à lire les
infos à ce sujet dans la référence ansi C++ de 1998. J'espère y voi r
plus clair.

Question annexe : puis-je changer le sujet de cette discussion pour y
ajouter « [Résolu] » histoire d'aider ceux qui sont dans la même
panade que moi ? Encore un grand merci pour la solution. Cela me tire
une grosse épine du pied.
Olivier Miakinen
Le #22637621
Bonjour,

Le 01/10/2010 21:16, Michel Pitermann a écrit :

Chez moi aussi :-) Mille mercis. Il s'agit visiblement de la gestion
de "locale" que je ne maîtrise pas assez bien. Je ne comprends pas ce
que Stroustrup voulait dire dans « The C programming language, third
edition » page 650 :

"Setting the global locale does not change the behavior of existing
streams that are using the previous value of the global locale. In
particular, cin, cout, etc., are not affected. If they should be
changed, they must be explicitly imbue()d."

On dirait que gcc fait le contraire.



Je n'y connais rien, mais dans ta citation de Stroustrup il est question
de cin et cou alors que dans le code proposé par Jean-Marc c'est
std::wcin et std::wcout... est-ce que la différence viendrait de là ?

Je venais de commencer à lire les
infos à ce sujet dans la référence ansi C++ de 1998. J'espère y voir
plus clair.



Tu nous tiens au courant ?

Question annexe : puis-je changer le sujet de cette discussion pour y
ajouter « [Résolu] » histoire d'aider ceux qui sont dans la même
panade que moi ?



Tu ne peux rien changer aux articles précédents. Je vois que tu passes
par Google groupes, alors peut-être crois-tu être sur un forum web et ne
connais-tu pas le fonctionnement d'Usenet ? En revanche, tu peux
parfaitement répondre en changeant le titre pour y ajouter [Résolu], et
résumer la réponse donnée.

Cordialement,
--
Olivier Miakinen

--
Olivier Miakinen
Jean-Marc Bourguet
Le #22638081
Michel Pitermann
fonctionne chez moi, dans quasiment les mêmes conditions.



Chez moi aussi :-) Mille mercis. Il s'agit visiblement de la gestion
de "locale" que je ne maîtrise pas assez bien. Je ne comprends pas ce
que Stroustrup voulait dire dans « The C programming language, third
edition » page 650 :

"Setting the global locale does not change the behavior of existing
streams that are using the previous value of the global locale. In
particular, cin, cout, etc., are not affected. If they should be
changed, they must be explicitly imbue()d."



J'ai le souvenir qu'il y a des implémentations qui en ont besoin (si je ne
trompe pas la SL de Dinkumware utilisée par MS). J'ai souvenir également de
discussions se concluant que la norme n'était pas claire sur ce point.

gcc m'a l'air de fixer la locale de cin, cout, wcin, wcout au moment de la
première action d'IO.

A+

--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
James Kanze
Le #22638521
On Oct 1, 6:27 pm, (Marc Espie) wrote:
In article
Michel Pitermann >Ce code :

>************************************************************

>#include <iostream>

>int main()
>{
> wchar_t c;
> while (std::wcin >> c) std::wcout << c;
> return 0;
>}

>*************************************************************

>ne fonctionne pas sur Ubuntu Lucid avec g++ 4.4.3 et un noyau
>2.6.32-25-server.

Au moins en C, il faut un setlocale(""); pour passer dans "la
locale par defaut". Un programme demarre avec la locale "C"
pour de betes raisons de securite (histoire de pouvoir avoir
un comportement reproductible independamment de
l'environnement de l'utilisateur).

Je ne suis pas pratiquant regulier des facets du C++ standard,
donc c'est peut-etre completement autre chose, mais ca me
parait coherent avec ce que tu observes.



En c++, l'équivalent est :
std::local::global(std::local(""));
Si le nouveau locale global a un nom (c'est normalement le cas
ici), cette fonction appelle setlocale, afin qu'un appel vaut
pour les deux langages.

--
James Kanze
Michel Pitermann
Le #22646061
> Je venais de commencer à lire les
> infos à ce sujet dans la référence ansi C++ de 1998. J'espère y voir
> plus clair.

Tu nous tiens au courant ?



Beaucoup de points restent flous dans ma tête malgré la lecture de la
référence ISO Ansi C++. En général, je m'en sors bien avec ce
document, mais dans ce cas il va falloir que je suive l'un ou l'autre
tutorial sur le sujet. Ma compréhension actuelle du comportement de g+
+ est que cin, cout, cerr, wcin, wcout et wcerr ne seraient pas
initialisés au départ avec la locale de l'environnement ou le sysème
par défaut de l'utilisateur (Ubuntu en UTF-8 dans mon cas), mais avec
la locale "C" ou un autre standard défaut. Il faudrait donc
impérativement utiliser :
std::local::global(std::local(""));
comme plusieurs personnes l'ont signalé si l'on veut traiter du texte
codé en UTF-8. Malheureusement, je n'ai rien trouvé sur le sujet dans
la doc de g++, mais je n'ai pas beaucoup cherché. Pour l'instant, il
est plus urgent que j'améliore mes connaissances sur la gestion de la
locale en C++ si je veux avancer. Cordialement.
Publicité
Poster une réponse
Anonyme