Jeux de caractères : MBCS/char* [Résolu]

Signaler
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
Salut,

Prenons le code suivant, qui affiche ce qu'il y a après le dernier \ de la chaîne :
<hr size="2" width="100%" />void test()
{
  char* lpPath = "c:\\toto";
  char* lpCurrent;
  char* lpLastBackSlash;
 
  lpCurrent = lpPath;
  lpLastBackSlash = lpCurrent;

  while (*lpCurrent)
  {
    if (*lpCurrent == '\\')
    {
      lpLastBackSlash = lpCurrent;
      lpLastBackSlash++;
    }
    lpCurrent++;
  }
  printf(lpLastBackSlash);
}
<hr size="2" width="100%" />A première vue pas d'erreur, ou du moins ça ressemble au genre de code que l'on peut s'attendre pour faire ce genre de chose : char* et incrémentation de pointeurs.

Ce code est compilé en MBCS, Multiple Byte Character Set. On a le choix entre MBCS et UNICODE, sachant que char* n'est pas du tout UNICODE, on ne peut compiler qu'en MBCS. Autrement dit, un caractère peut faire plusieurs octets.

Autrement dit, ce code est potentiellement faux, dans le cas où lpPath viendrait par exemple de GetCurrentDirectory. Potentiellement faux revient à dire qu'il est faux...

Il faudrait utiliser _mbsinc (Ou _tcsinc) pour incrémenter les pointeurs et _mbccmp (Ou _tccmp) pour comparer les caractères.

Mais on peut pas dire que ce soit des fonctions couramment utilisées...

Des réflexions sur le sujet ?

5 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
Un prog qu'on sait devoir distribuer aussi dans les pays exotiques DOIT être compilé en UNICODE, les problèmes de MBCS avec quelle page de code est en vigueur sont révolus. Windows travaille complètement UNICODE en interne donc tout va bon.
Le lien que tu as donné est obsolète, d'une époque où UNICODE arrivait seulement.


Utilise TCHAR au lieu de char, ça passera partout et tes pointeurs se déplaceront toujours comme il se doit.


Exemple que tu pourras compiler comme tu veux:
void __stdcall AppPathInitialize()
{
  TCHAR szthis[300];
  TCHAR* c = szthis + GetModuleFileName(0, szthis, 300);  while(*c !'\\') c--; *c 0;
  SetCurrentDirectory(szthis);
}

ciao...
BruNews, MVP VC++
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
... hein ???

"dans le cas où lpPath viendrait par exemple de GetCurrentDirectory"

À moins que je me trompe, il existe 2 versions de cette fonction : GetCurrentDirectoryA et GetCurrentDirectoryW
La première étant pour l'ascii, l'autre pour le UNICODE. GetCurrentDirectory sera transformée en une ou l'autre de ces fonctions par le préprocesseur selon que tu utilises unicode ou mbcs. Je ne vois donc pas où est le problème.
Même chose pour LPTSTR qui sera transformé en LPSTR ou LPWSTR.

De toute façon, char est utilisé pour ascii et wchar_t pour UNICODE qui correspond, si ma mémoire est bonne, à une sorte de short. Il y aura très certainement des erreurs de compilation si tu essais d'utiliser l'un avec un code fait pour l'autre.

Ceci dit, je ne comprend pas trop ta reflexion... peut-être veux tu dire autre chose.

"Il faudrait utiliser _mbsinc (Ou _tcsinc) pour incrémenter les pointeurs"

Incrémenter un pointeur via une fonction... on croirait de l'interpréter.

C++ (@++)<!--
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
Salut SAKingdom,

En fait le problème que je tente de soulever n'a rien à voir avec l'Unicode. Je travaille ici, comme la plupart des gens sur ce site, en MBCS.

Donc j'utilise effectivement GetCurrentDirectoryA.

GetCurrentDirectoryA me renverra du MBCS.
Donc elle peut me renvoyer des caractères codés sur plusieurs octets.
Donc je ne peux pas utiliser l'incrémentation de pointeurs, le == pour la comparaison...

Dans la majorité des cas, incrémenter le pointeur fonctionne, car GetCurrentDirectory me renvoie des chaînes où un caractère correspond à un octet...

Mais dans quel cas cela ne fonctionne-t-il pas ? Sur les Windows Chinois ? Japonais ?

Et pourquoi (presque ?) tout le monde se fiche de _mbsinc ?
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
Oki, merci.