Formater string C/C++ avec caractères spéciaux sous Linux [Résolu]

Messages postés
31
Date d'inscription
lundi 2 juin 2008
Dernière intervention
22 avril 2011
- - Dernière réponse : zaraki21
Messages postés
31
Date d'inscription
lundi 2 juin 2008
Dernière intervention
22 avril 2011
- 27 avril 2010 à 09:16
Bonjour,

Je développe actuellement une application C/C++ sous Linux destinée a un périphérique électronique embarqué. Je dois dans l'implémentation écrire une fonction qui communique avec un écran LCD externe. Cette fonction doit obligatoirement prendre en paramètre d'entrée une chaîne de caractères qui va être ensuite stocker dans un message de type "unsigned char" pour être envoyé au LCD. Tout fonctionnait jusqu'à maintenant mais le problème désormais, est d'afficher des caractères spéciaux tel que Ä,ä ou encore ö, Ö. Ces dernier étant codés sur 2 octets, mon programme ne fonctionne plus correctement, les caractères ne sont pas affichés comme ils le devraient. Après plusieurs recherches sur Internet, j'ai vu qu'il fallait que j'utilise par exemple le type "wchar_t" mais seulement voila, je ne peux pas changer le type d'entrée qui est "string" et ne peux pas avoir recours aux fonctions (fonctions non reconnues dans mon application par le compilateur) tels que "swprintf" ou encore "mbstowcs". A noter que je travaille avec un répertoire de librairie restreint du fait du caractère embarqué de l'application. Donc si quelqu'un a une idée, merci.

Code de la fonction dans le cas ou cela fonctionne avec des caractères non spéciaux :
void LCD::writeLCDMessage(std::string sParameter){
        size_t size = sParameter.size() + 1;
        char * buffer = new char[ size ];                         
strncpy(buffer, sParameter.c_str(), size);
int sizeDisplay=0;
sizeDisplay = strlen(buffer);
unsigned char pDisplayMessage[sizeDisplay];
for(int i=0; i<sizeDisplay; i++){
pDisplayMessage[i]=buffer[i];                         
}
write(lcd,pDisplayMessage,sizeof(pDisplayMessage));      
delete [] buffer;                                         
}
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
Messages postés
31
Date d'inscription
lundi 2 juin 2008
Dernière intervention
22 avril 2011
3
Merci
En fait, c'est bon j'ai trouvé un code sur le net pour transformer une "string" en "wchar_t" :
template <typename InputIterator,typename OutputIterator>
OutputIterator utf8_to_wchar_t(InputIterator  begin,InputIterator  end,OutputIterator result){
for (; begin != end; ++begin, ++result){
int count      = 0; // the number of bytes in the UTF-8 sequence
unsigned c     = (unsigned char)*begin;
unsigned i     = 0x80;
    
if (c == 0xEF){
c = (unsigned char)* ++ ++ ++begin;
}
// Resynchronize after errors
    while ((c & 0xC0) == 0x80){
    	c = (unsigned char)*++begin;
    }
// Now we count the number of bytes in the sequence...
for (; c & i; i >>= 1){
++count;
}
// ...and strip the high-code-bits from the character value
c &= i - 1;
// Now we build the resulting wchar_t by appending all the character bits together
for (; count > 1; --count){
c <<= 6;
    c |=  (*++begin) & 0x3F;
}
// And we store the result in the output container
*result = c;
}
// The usual generic stuff
return result;
}


Après j'ai utilisé cette méthode en l'adaptant à mes besoins pour ainsi récupérer la "string" passée en paramètre dans un tableau "vector" de "wchar_t". Ensuite il a été facile de passer en "unsigned char" par la suite.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de zaraki21
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
0
Merci
Librairie => bibliothèque (librairie est une grossière erreur de traduction du mot "library").

Tout d'abord, un petit problème qui n'a certes rien à voir, mais qui va te pourrir la vie: attention à la copie des arguments !
Ceci serait vraiment mieux:
void LCD::writeLCDMessage(const std::string& sParameter)

Tu gagne énormément en perf juste en faisant cela, sans incidence sur ton code. C'est encore plus flagrant en système embarqué !


Pour répondre à ton problème, tu peux utiliser: std::wstring et wchar_t. Normalement tu trouveras tout les fonctions nécessaires dans <cstdlib>. Si tu ne peux changer le std::string tu es très très mal. Il te faudra convertir ton std::string en std::wstring, et ce sera l'horreur.

Autre question: Tu ne peux pas faire: write(lcd, sParameter.c_str(), sParameter.size()); ?

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Commenter la réponse de cptpingu
Messages postés
31
Date d'inscription
lundi 2 juin 2008
Dernière intervention
22 avril 2011
0
Merci
Ok, merci pour les astuces et conseils de programmation. Tout d'abord au niveau du "write" avec lcd, non je dois faire comme j'ai fais avant car sinon il y a des problèmes d'affichages sur le LCD. Sinon à part ça je crois pas pouvoir changer string en wstring car en fait si tu veux le message est saisi bien un formulaire donc je sais pas. Enfin, je vais essayer d'utiliser <cstdlib> et voir ce que ça donne.
Commenter la réponse de zaraki21
Messages postés
31
Date d'inscription
lundi 2 juin 2008
Dernière intervention
22 avril 2011
0
Merci
En fait, je rencontre des problèmes pour l'utilisation de wstring ; en effet même en incluant <cstdlib>, le compilateur me met comme erreur "wstring in namespace std does not name a type" et je n'ai pas trouvé de solution à ce problème. J'ai aussi trouvé une fonction qui pourrait me permettre de faire ce que je veux c'est swprintf mais toujours pareil j'ai une erreur de compilation quand j'essaye de l'utiliser "swprintf was not declared in this scope" donc je suis un peu dans l'impasse. De plus, j'ai essayé sur un autre ordinateur d'utiliser ces deux éléments et cela fonctionne donc à mon avis il doit y avoir un problème au niveau du compilateur utilisé, je pense notamment à uclibc, tu en penses quoi ?
Commenter la réponse de zaraki21

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.