Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [SFML 2.0] sf::String et std::ifstream problème d'encodages  (Lu 7082 fois)

0 Membres et 1 Invité sur ce sujet

Flaco

  • Newbie
  • *
  • Messages: 36
  • Glory to Arztotzka!
    • Voir le profil
    • Core Unit
    • E-mail
[SFML 2.0] sf::String et std::ifstream problème d'encodages
« le: Août 28, 2012, 07:25:29 pm »
Bonjour, désolé si le titre n'est pas clair.

Voila mon problème, j'utilise SFGUI et j'ai un problème pour afficher les caractères accentués (que je tire d'un fichier),
ledit fichier (.txt) est bel et bien encodé en utf-8. Alors j'ai posté ma question sur leur forum: Displaying UTF-8 encoding with a string.c_str() in a sfg::Label.

Et le vrai soucis, c'est que je ne comprend pas la réponse. Car je n'ai jamais été confronté à des soucis d'encodage et je ne comprend pas bien comment utiliser sf::Utf.
Lors-ce que j'envoie une sf::String(L"éèà"); à un sfg::Label et que je l'affiche sur la GUI. Pas de soucis avec les accents, etc... mais j'aimerais faire ça avec des lignes de caractères tirées d'un fichier (avec un std::getline()).

Voila la partie du code ou je fait ça:
  std::string standardLine;
  std::getline(fileStream, standardLine);
  sf::String SFLine = standardLine;
 

Voila, comment faire pour convertir ma sf::String en une sf::String UTF-8? (C'est bien ce que l'ont fait lors-ce que on met un "L" devant la chaîne de caractère non?)
Car, en gros, j'ai besoin de passer au sfg::Label une chaîne comme ceci: sfg::Label::Create(L"Voilà"); pour afficher les caractères spéciaux. J'aimerais lui envoyer la sf::String comme cela.

PS: si je met un std::cout << standardLine << std::endl; les accents s'affichent sans aucun soucis.

Merci à vous!
« Modifié: Août 28, 2012, 07:27:32 pm par Flaco »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #1 le: Août 28, 2012, 07:35:46 pm »
Regarde la doc du constructeur de sf::String qui prend un std::string en paramètre : il fait l'hypothèse que ce qui est dans la chaîne est encodé avec la locale courante, qui n'est donc pas forcément UTF-8.

Il te faudrait plutôt une fonction du genre sf::String::fromUtf8, malheureusement pour toi celle-ci n'existe pas. Il faut donc faire la conversion toi-même, en UTF-32 puisque c'est le seul encodage Unicode que sf::String est capable de gérer directement. Pour faire cette conversion, il faut utiliser la classe sf::Utf8 et sa fonction toUtf32.

std::basic_string<sf::Uint32> utf32;
sf::Utf8::toUtf32(standardLine.begin(), standardLine.end(), std::back_inserter(utf32));

sf::String SFLine = utf32;
Laurent Gomila - SFML developer

Flaco

  • Newbie
  • *
  • Messages: 36
  • Glory to Arztotzka!
    • Voir le profil
    • Core Unit
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #2 le: Août 28, 2012, 08:13:37 pm »
Merci pour ta réponse et ton aide Laurent.
J'ai suivi tes consignes et, en effet, le code compile mais les accents ne sont toujours pas affichés (là ça devient un problème du côté de SFGUI si je ne me trompe).
Je vais poster ça sur leur forum.

Mais je me demandais: quand j'écris sf::String myString(L"Héhé"); que signifie ce "L"?
J'ai lu sur le tutoriel de la 1.6
Citer
Vous pouvez également utiliser des chaînes de caractères larges, si vous comptez utiliser du texte unicode
.
C'est ce que je fais en passant ma std::String en utf32? Je la défini comme une chaine de caractères large?

PS: Merci pour le tuto sur le Module Audio dans la 2.0 et bon courage pour la suite! :)


EDIT: Problème résolu, au lieu d'envoyer à SFGUI la sf::String je lui ai envoyé la std::basic_string. Les accents s'affichent.. bizarre que la sf::String ne passe pas non?
« Modifié: Août 28, 2012, 08:25:48 pm par Flaco »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #3 le: Août 28, 2012, 08:49:19 pm »
Citer
Mais je me demandais: quand j'écris sf::String myString(L"Héhé"); que signifie ce "L"?
Une chaîne "blabla" est un const char*, donc 8 bits utilisant l'encodage du fichier source. Une chaîne L"blabla" est un const wchar_t, donc 16/32 bits (selon l'OS) et utilisant généralement un encodage Unicode (UCS2 ou UTF-32).

Mais tu devrais lire un bon tutoriel sur les encodages, c'est typiquement le truc qui paraît compliqué quand on n'y connaît rien mais qui est en fait ultra-simple. Je me souviens que j'avais croisé des tutoriels vraiment bons pour expliquer clairement les encodages à ceux qui s'embrouillent complètement avec ça :)

Citer
Problème résolu, au lieu d'envoyer à SFGUI la sf::String je lui ai envoyé la std::basic_string. Les accents s'affichent.. bizarre que la sf::String ne passe pas non?
Là oui, y a un problème. Mais je me doutais qu'il y avait un truc pas clair, puisque std::cout fonctionnait aussi (et il utilise aussi la locale courante, comme sf::String quand tu lui passes un std::string).

Pourrais-tu tester avec une chaîne simple ("é") et me donner quelques informations :
- la valeur des caractères dans ta std::string UTF-8
- la valeur du caractère converti dans ta sf::String
- le nom de ta locale par défaut
std::cout << std::locale().name() << std::endl;
- le nom de la locale de std::cout
std::cout << std::cout.getloc().name() << std::endl;
« Modifié: Août 28, 2012, 08:52:47 pm par Laurent »
Laurent Gomila - SFML developer

Flaco

  • Newbie
  • *
  • Messages: 36
  • Glory to Arztotzka!
    • Voir le profil
    • Core Unit
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #4 le: Août 28, 2012, 09:01:39 pm »
Qu'entends tu par "valeur du caractère"?

Voila le nom de ma locale par défaut: C

Si par "valeur" tu entends ce que je pense voila:

(Sur un std::cout)
std::string line1("é"); retourne é
sf::String line2 = line1; retourne 4294967295


Merci à toi (et j'espère ne m'être pas planté pour cette histoire de valeur).


EDIT: Si besoin, voila plus d'infos:

OS: Gnu/Linux 32bits
Distribution: Ubuntu 12.04LTS
Compilateur: GCC (G++) 4.6.3.

EDIT²: Et merci pour le conseil, j'me lirais un tutoriel sur l'encodage! :)
« Modifié: Août 28, 2012, 09:05:53 pm par Flaco »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #5 le: Août 28, 2012, 10:40:42 pm »
Un caractère (char) est un entier. Donc par valeur je veux vraiment dire la valeur des caractères des chaînes.

for (std::size_t i = 0; i < chaine_utf8.size(); ++i)
    std::cout << int(chaine_utf8[i]) << " ";
std::cout << std::endl;

for (std::size_t i = 0; i < chaine_sfml.getSize(); ++i)
    std::cout << int(chaine_sfml[i]) << " ";
std::cout << std::endl;

Tu as aussi oublié la locale de std::cout.
Laurent Gomila - SFML developer

Flaco

  • Newbie
  • *
  • Messages: 36
  • Glory to Arztotzka!
    • Voir le profil
    • Core Unit
    • E-mail
Re : Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #6 le: Août 28, 2012, 11:06:04 pm »
Tu as aussi oublié la locale de std::cout.

Ah mais ça  était pas! ^^

Je connaissais l'astuce du int variable(é); pour afficher sa valeur ASCII. Mais je savais pas qu'on pouvait faire comme ça, merci à toi. Donc les quatre résultats sont:

std::string line1("é") retourne -61 -87
sf::String line2 = line1 retourne -1 -1
std::locale().name() retourne C
std::cout.getloc().name() retourne C

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #7 le: Août 28, 2012, 11:21:48 pm »
Citer
sf::String line2 = line1 retourne -1 -1
Euh, avec la conversion qui marche ce serait mieux ;D

Citer
std::cout.getloc().name() retourne C
Oui en fait c'est l'encodage de la console qui compte, je me suis trompé. Et du coup la console utilise de l'UTF-8 sous Linux, donc normal que ça t'affiche ton texte sans problème.
Laurent Gomila - SFML developer

Flaco

  • Newbie
  • *
  • Messages: 36
  • Glory to Arztotzka!
    • Voir le profil
    • Core Unit
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #8 le: Août 28, 2012, 11:32:59 pm »
Heu donc.. c'est normal tout ça? Est-ce que si je compile sous OS X ou Windows j'aurais un soucis (au pire, j'verrais à ce moment là. Et j'ai le temps).

Désolé pour la conversion, je commence à fâtiguer. ::)

Donc si l'output iterator est std::basic_string<sf::Uint32> utf32 (comme sur ton exemple plus haut) je devrais écrire:

sf::String line2 = utf32; retourne 233 (ça sonne moins faux là.. non?  :D )

Voila, merci à toi.


EDIT: Bon, comme tu dois t'en douter: j'ai juste foiré au moment du sf::String line2 = utf32; donc en fait.. y'a jamais eu de problème (si ce n'est mon ignorance et mon incompétence).
Désolé de t'avoir pris autant de temps et merci d'avoir consacré une partie de celui-ci à enseigner les ficelles à un newbie comme moi!  :-X
En tout cas j'ai appris pleins de choses et je te remercie. Je ferais plus attention à ce genre d'erreurs toutes bêtes à l'avenir (et au moins j'ai bien compris le sens de "output iterator" maintenant  ::) )

Bonne soirée à toi :)
« Modifié: Août 28, 2012, 11:44:29 pm par Flaco »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] sf::String et std::ifstream problème d'encodages
« Réponse #9 le: Août 29, 2012, 08:20:01 am »
Arg :P

Bon, ça me rassure tout ça.
Laurent Gomila - SFML developer