Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Gestion des caractères internationaux

8 réponses
Avatar
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 =E9t=E9 compil=E9 sans options (g++
aa.cc). Le programme arr=EAte la lecture de l'entr=E9e standard sur le
premier caract=E8re non ascii. Par exemple, donner "azert=E9qsdfg" ne
traitera que "azert" et s'arretera sur "=E9". Mon environnement est
int=E9gralement initialis=E9 en UTF-8. Est-ce normal ?

8 réponses

Avatar
espie
In article ,
Michel Pitermann wrote:
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.
Avatar
Michel Pitermann
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.
Avatar
Jean-Marc Bourguet
Michel Pitermann writes:

#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
Avatar
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."

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.
Avatar
Olivier Miakinen
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
Avatar
Jean-Marc Bourguet
Michel Pitermann writes:

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
Avatar
James Kanze
On Oct 1, 6:27 pm, (Marc Espie) wrote:
In article
,
Michel Pitermann wrote:
>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
Avatar
Michel Pitermann
> 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.