[c++] string et é

string et é [c++] - C++ - Programmation

Marsh Posté le 03-08-2005 à 18:29:50    

:hello:  
 
J'ai rencontré un problême lors de l'utilisation de la class string. Ne trouvant pas d'où il pouvait venir je me suis décidé à essayer de le reproduire dans un code minimal, et j'y suis arrivé.
Je precise que je programme sous linux.
 
Voici le fameaux code.

Code :
  1. #include <string.h>
  2. using namespace std;
  3. #include <iostream>
  4. main()
  5. {
  6. string str("test" );
  7. str.insert(3,"é" );
  8. str.insert(4,"é" );
  9. cout<<str<<"\n";
  10. str.insert(5,"é" );
  11. cout<<str<<"\n";
  12. }


 
Voici le résultat dans le terminal

Code :
  1. tes���t
  2. tes��t


Les caractères byzarres semblent être des caractères non reconnue.
 
Je précise que ce code fonctionne bien

Code :
  1. main()
  2. {
  3. string str("test" );
  4. str.insert(3,"é" );
  5. str.insert(3,"é" );
  6. cout<<str<<"\n";
  7. str.insert(2,"é" );
  8. cout<<str<<"\n";
  9. }


Code :
  1. teséét
  2. teéséét


 
 
Après quelques tests j'ai conclue que le problême se pose lorsqu'on ajoute un "é" directement après un "é"

Reply

Marsh Posté le 03-08-2005 à 18:29:50   

Reply

Marsh Posté le 03-08-2005 à 18:56:21    

problème de jeu de caractère : ton source n'est pas écrit avec le même jeu de caractères que celui qu'utilise ton terminal ... Problème déjà abordé plusieurs fois sur ce forum :o
 
Edit : Tu aurais un 'é' qui passe tout de même ? :heink:


Message édité par theshockwave le 03-08-2005 à 18:57:36
Reply

Marsh Posté le 03-08-2005 à 19:17:19    

theshockwave a écrit :

problème de jeu de caractère : ton source n'est pas écrit avec le même jeu de caractères que celui qu'utilise ton terminal ... Problème déjà abordé plusieurs fois sur ce forum :o
 
Edit : Tu aurais un 'é' qui passe tout de même ? :heink:


 
ben oui
 
par ex: cout<<"ééééééééé\n"; fonctionne très bien.
 
Ca n'a pas l'air d'être un probleme de jeu de caractère source/console.
 
Encore plus byzarre:

Code :
  1. main()
  2. {
  3. cout<<"ééééééééééééééé\n\n";
  4. string str("tes" );
  5. cout<<str<<"               "<<str.length()<<"\n";
  6. str.insert(3,"t" );
  7. cout<<str<<"               "<<str.length()<<"\n";
  8. str.insert(3,"é" );
  9. cout<<str<<"               "<<str.length()<<"\n";
  10. str.insert(4,"é" );
  11. cout<<str<<"               "<<str.length()<<"\n";
  12. }


 
 

Code :
  1. ééééééééééééééé
  2. tes               3
  3. test               4
  4. tesét               6
  5. tes���t               8


 
Regardez les longueurs ...


Message édité par ffomnislash le 03-08-2005 à 19:21:41
Reply

Marsh Posté le 03-08-2005 à 20:29:11    

ben çà dépend de ton codage de caractère, les std::string ignorant complètement tout ça. Ça dépend aussi si tu utilises le meme codage dans ton éditeur et dans ton terminal ... si c'est utf-8, le é est représeté par 2 octets. Une seule réponse : glib::ustring qui gère ça pas trop mal. J'ai donné un exemple y a pas longtemps

Reply

Marsh Posté le 03-08-2005 à 22:13:45    

Ok merci de ton aid Taz.
 
J'ai regardé et mon editeur est en UT8 ainsi que la console.
 
J'ai essayé de mettre en place la méthode avec glib::ustring dont tu donne un exemple dans un sujet.
J'ai installé glibmm,configuré le make pour qu'il trouve les headers mais j'ai cette erreur:
 

/usr/include/c++/3.3/bits/stl_threads.h:69: error: '__gthread_mutex_t' is used  
   as a type, but is not defined as a type.


 
D'autres erreurs suivent mais avec de la chance la correction de celle là "corrigera" les autres. Apperemment c'est un type qui n'est pas défini, je ne vois pas trop ce que je peut faire :/
 
C'est bien sur la 1ere erreur qui apparait.
 

Reply

Marsh Posté le 03-08-2005 à 22:44:08    

tu compiles comment ?

Reply

Marsh Posté le 03-08-2005 à 22:52:47    

g++ -o accents accents.cpp  -I/usr/include/glibmm-2.4/ -I/usr/include/glib-2.0/ -I/usr/lib/glibmm-2.4/include  -I/usr/lib/glib-2.0/include/ -I/usr/include/sigc++-2.0/sigc++/


 
Il n'y a pas de makefile parceque c'est juste un programme de test sinon j'utilise bien sur des makefiles.

Reply

Marsh Posté le 03-08-2005 à 22:58:32    

spa comme ça :o
 
g++ $(pkg-config --cflags --libs glibmm-2.4) -Wall chars.cpp
 
si tu fais un Makefile, mets
 
CXXFLAGS:=$(shell pkg-config --cflags glibmm-2.4)
LDFLAGS:=$(shell pkg-config --libs glibmm-2.4)

Reply

Marsh Posté le 03-08-2005 à 23:19:52    

Encore merci, en effet cela fonctionne mieux. J'en reviens donc au premier problemes qui est les locales.
 
J'ai compilé le code que tu donne à ce lien:
http://forum.hardware.fr/forum2.ph [...] 5#t1141435
 
De ce que j'ai compris il permet de dire a std quel locale utiliser, de forcer l'utilisation d'une locale.
 
Le résultat:

Code :
  1. é
  2. é
  3.         ffffffc3 -> '�
  4.         ffffffa9 -> '�'


 
Donc il y a toujours le probleme.
J'ai fait une recherche du coté de std:setlocal et apperemment il faudrait lui dire une locale ...
j'ai fait divers tests:
- std::setlocale(LC_ALL, "UTF8" );
- std::setlocale(LC_ALL, "fr_FR@euro" );
 
L'exception est à chaque fois levée :/. Pourtant google me renvoie bien vers du code de ce genre .


Message édité par ffomnislash le 03-08-2005 à 23:20:19
Reply

Marsh Posté le 03-08-2005 à 23:33:47    

montre tes locales. parce que moi je suis en tout utf-8, donc je saisis de l'utf-8. Toi peut etre pas. Regarde la doc de glibmm, il y a ce qu'il faut pour créer de ustring à partir d'autres locales.

Reply

Marsh Posté le 03-08-2005 à 23:33:47   

Reply

Marsh Posté le 03-08-2005 à 23:37:45    

Justement je suis en UTF8  

ffomnislash@Thor:~$ locale
LANG=fr_FR.UTF-8
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=


 
Si je fait std::setlocale(LC_ALL, "fr_FR.UTF-8" ); j'ai pas d'erreur mais j'ai pas d'accent non plus.
 

é
é
        ffffffc3 -> '�
        ffffffa9 -> '�'
 
é
        e9 -> 'e9'


Reply

Marsh Posté le 04-08-2005 à 00:48:58    

reprends mon programme tel quel et mets LC_ALL=fr_FR.UTF-8

Reply

Marsh Posté le 04-08-2005 à 01:01:11    

Je comprends pas la  
Comment tu veus que je mette LC_ALL=fr_FR.UTF-8 ?
Déjà LC_ALL est un entier donc ...
 
ton programme

Code :
  1. namespace
  2. {
  3. template<typename Seq>
  4. void dump(const Seq& s)
  5. {
  6.  typedef typename Seq::const_iterator const_iterator;
  7.  std::cout << s << '\n';
  8.  for(const_iterator i(s.begin()); i != s.end(); ++i)
  9.  {
  10.   std::cout << '\t'
  11.   << std::hex << static_cast<int>(*i) << " -> '" << *i << "'\n";
  12.  }
  13.  std::cout << '\n';
  14. }
  15. }
  16. main()
  17. {
  18. try
  19. {
  20.  std::setlocale(LC_ALL, "" );
  21.  std::string line;
  22.  while(std::getline(std::cin, line))
  23.  {
  24.   dump(line);
  25.   dump(Glib::ustring(line));
  26.   std::cout << '\n';
  27.  }
  28. }
  29. catch(Glib::Exception &ce)
  30. {
  31.  std::cerr << ce.what() << '\n';
  32. }
  33. }


Message édité par ffomnislash le 04-08-2005 à 01:01:53
Reply

Marsh Posté le 04-08-2005 à 01:04:26    

non, dans ton environement, fais en sorte que LC_ALL ait la meme valeur que LANG

Reply

Marsh Posté le 04-08-2005 à 01:18:10    

Taz a écrit :

non, dans ton environement, fais en sorte que LC_ALL ait la meme valeur que LANG


 
mdr pas fait attention à tout ca, je comprend mieux le lien entre le code et le systeme maintenant  
Je verrais ca demain, il commence à se faire tard, merci de ton aide.

Reply

Marsh Posté le 04-08-2005 à 01:19:33    

ok

Reply

Marsh Posté le 04-08-2005 à 13:01:05    

Je n'ai toujours pas réussi à faire fonctionner tous ceci.
 

ffomnislash@Thor:~/projet_sdl/test$ locale
...
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=fr_FR.UTF-8


 
Je n'ai toujours pas les "é" qui s'affichent correctement.

ffomnislash@Thor:~/projet_sdl/test$ ./accents  
é
é
        ffffffc3 -> '�
        ffffffa9 -> '�'
 
é
        e9 -> 'e9'


 
Alors je ne comprend plus rien :/
 
Sinon j'ai lu sur un site qu'il ne fallait pas définir LC_ALL car c'était justement les programmes qui l'utilisait dans le cas où ils utilisent une locale particulière. Je suppose que c'est ce que setlocal() fait justement.
 
 
edit --
Je vais préciser mon probleme.
Que l'affichage en terminal ne soit pas correcte ca ne me dérange pas en faite. mon problême se situe à l'intérieur du code.
J'ai un string qui subit diverses opération d'insertion de string. Comme dans le code donné dans le premier message. Il faudrait que je puisse comparer les caractères de cette chaine à d'autres caractères. En faite il faudrait pouvoir faire ca.
 


string str("test" );
str.insert(..,..);
char caractere=str[i];
if(caractere=='é')
...


Le compilateur me mettait un warning pour le 'é', ceci en raison des 2 octets je pense.
J'ai donc enlevé le type char pour y mettre des string à la place.
Mais str[i] n'est pas correcte, d'ailleur str.length() n'est pas correcte non plus. Un caractere est ajouté à chaque 'é'. (toujours les 2 octets ...)
 
Je précise car peut être que ceux ci est resolvable d'un manière plus simple, qui sait, peut être que j'ai de la chance :D.


Message édité par ffomnislash le 04-08-2005 à 14:53:21
Reply

Marsh Posté le 04-08-2005 à 14:59:41    

et elle te dit quoi l'exception que tu prends dans la tête ? parce que ta trace d'exécution elle est pas complète là.

Reply

Marsh Posté le 04-08-2005 à 15:11:27    

ben un é en terme de char ça en prend 2 (variable selon les caractères). en terme de gunichar, ça prend toujours 1. n'utilise que des "chaînes" pour représenter toute entité unicode/utf-8

Reply

Marsh Posté le 04-08-2005 à 15:50:36    

Mais est il possible de faire en sorte que les opérations effectué sur le type string gère correctement le fait que certains caractères sont multioctets, de manière à ce que les opérations (length() par ex) soit correcte?
 
Pour la trace d'éxecution elle est bien complète, je n'ai pas d'erreur lors que j'utilise ton code tel quel et que je définit LC_ALL.

Reply

Marsh Posté le 04-08-2005 à 19:24:02    

ben size() est correcte, je vois pas le problème.

Reply

Marsh Posté le 04-08-2005 à 20:30:36    

ben ...
 

Code :
  1. string str("tes" );
  2.  cout<<str<<"               "<<str.size()<<"\n";
  3.  str.insert(3,"t" );
  4.  cout<<str<<"               "<<str.size()<<"\n";
  5.  str.insert(3,"é" );
  6.  cout<<str<<"               "<<str.size()<<"\n";
  7.  str.insert(4,"é" );
  8.  cout<<str<<"               "<<str.size()<<"\n";


 

Code :
  1. tes               3
  2. test               4
  3. tesét               6
  4. tes���t               8


 
:/

Reply

Marsh Posté le 04-08-2005 à 20:51:17    

t'es grave, je perds mon temps.

Reply

Marsh Posté le 05-08-2005 à 13:00:00    

Taz a écrit :

t'es grave, je perds mon temps.


 
Tu a raison, je suis grave  :sweat:  
 
Il faut bien sur que j'utilise ustring et non string.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed