Un tableau qui se remplit avec des'\0' entre chaque caractère ?

Résolu
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008 - 9 avril 2008 à 10:01
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 - 11 avril 2008 à 16:13
Bonjour à tous,

Je suis actuellement entrain de coder un programme en langage C permettant d'intéragir avec un lecteur RFID Skyetek M9. Skyetek fournit une API qui ma fois ne fonctionne pas trop mal hormis un petit détail. En effet, les tableaux de caractères contenu à l'intérieur des structures sont remplis à l'aide de caractères et de '\0' qui sortent de nul part. Supposons que j'ai un pointeur sur structure, cette structure contient un tableau nommé nom de 128 caractères. Ce tableau contient alors les données suivantes : {'S', '\0', 'k', '\0', 'y', '\0', etc...}Ce qui fait que lorsque je fais un printf du genre printf("Nom : %s", ptr->nom) et bien il ne m'affiche que le 'S', ce qui est normal puisqu'une fin de chaine est détectée après ce premier caractère. Ma question est, à quoi cela pourrait t'il être du? Je développe à l'aide de Dev C++ sur un environnement Windows.

Bien sur je pourrais contourner le problème en écrivant une fonction qui me réorganise le tableau bien correctement, mais travaillant sur un système embarqué, je n'ai pas des ressources processeurs illimités.

Toute piste de réflexion est la bienvenue.

Par avance merci,

33 réponses

cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 10:09
Bonjour,

Ca ressemble à une chaîne de caractères UNICODE : chaque caractère est sur 2 octets et les caractères ASCII sont sur la page 0 !

Jean-François
3
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 14:04
Il faudrait donc que l'encodage de mes chaines de caractères soit de type ASCII ??
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 14:17
Si l'API fournie est en UNICODE, il faut faire un programme UNICODE ! Ca sera plus simple que de convertir d'un format à l'autre. Mais peut être y-a-t'il une version ASCII de cette API ?

Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 14:22
Oui mais le seul problème c'est que même sur un exemple de test fournit avec l'API j'ai ce problème...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 14:25
C'est un exemple qui compile en UNICODE ?

Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 14:27
Comment puis je le savoir?
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 14:37
Je ne connais pas Dev C++ ! Mais y-a-t'il au début de l'exemple (avant les includes) un : #define UNICODE

Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 14:49
Rien de tout ca. Y'a t'il possibilité de mettre une #define ASCII alors? :D
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 15:04
Pas à ma connaissance ! Si c'est pas UNICODE c'est ASCII. La structure qui pose problème est renseignée par les fonctions de l'API ?

Jean-François
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 15:42
Le compilateur (le préprocesseur en fait) n'a aucune raison de refuser un #define ASCII mais c'est pas pour ça que cela sera pris en compte ! La constante ASCII sera créée tout simplement ! A ma connaissance il faut mettre #define UNICODE pour passer en UNICODE, si on ne le met pas on reste en ASCII, c'est comme cela que je l'utilise.

Pouvez-vous poster l'exemple qui est fourni avec l'API (ou un extrait avec la structure) ?
Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 15:54
Oula pardon pour ses doublons, je ne sais pas ce qui c'est passé...

Voici un programme d'exemple fournit avec l'API :

// sloop.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SkyeTekAPI.h"
#include "SkyeTekProtocol.h"

// stop flag
bool isStop = false;

FILE *fp = NULL;
void debug(char *msg)
{
  char *p = strstr(msg,"\r");
  if( p != NULL )
  {
    *p++ = '\n';
    *p = '\0';
  }
  if( fp != NULL )
    fprintf(fp,msg);
  else
    printf(msg);
}

//
//  FUNCTION: SelectLoopCallback(LPSKYETEK_TAG, void *)
//
//  PURPOSE:  Callback called by SkyeTek_SelectTags whenever
//            a tag is selected. This returns 1 to continue
//            and zero to stop.
//
//
unsigned char SelectLoopCallback(LPSKYETEK_TAG lpTag, void *user)
{
  if( !isStop )
  {
    if( lpTag != NULL )
    {
      printf("Tag: %s; Type: %s\n", lpTag->friendly, SkyeTek_GetTagTypeNameFromType(lpTag->type));
      SkyeTek_FreeTag(lpTag);
    }
  }
  return( !isStop );
}

//
//  FUNCTION: ThreadProc(LPVOID)
//
//  PURPOSE:  Main thread function. It sits in a loop until the
//            reader is discovered and then it calls the
//            SkyeTek_SelectTags function, which does not return
//            until the loop stops. To stop the loop, the
//            SelectLoopCallback needs to return zero.
//
//
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    LPSKYETEK_DEVICE *devices = NULL;
    LPSKYETEK_READER *readers = NULL;
  SKYETEK_STATUS st;
  unsigned int numDevices;
  unsigned int numReaders;

  // comment this out to disable debug
  SkyeTek_SetDebugger(debug);

  printf("Discovering reader...\n");
  while( !isStop )
  {
      numDevices = SkyeTek_DiscoverDevices(&devices);
    if( numDevices == 0 )
    {
      Sleep(100);
      continue;
    }
    if( isStop )
      return 1;

      numReaders = SkyeTek_DiscoverReaders(devices, numDevices, &readers);
    if( numReaders == 0 )
    {
      SkyeTek_FreeDevices(devices,numDevices);
      Sleep(100);
      continue;
    }
    break;
  }

  // set reader info
  printf("Found reader: %s\n", readers[0]->friendly);

  // the SkyeTek_SelectTags function does not return until the loop is done
  printf("Entering select loop...\n");
  st = SkyeTek_SelectTags(readers[0],AUTO_DETECT,SelectLoopCallback,0,1,NULL);
  if( st != SKYETEK_SUCCESS )
    printf("Select loop failed\n");
  printf("Select loop done\n");

  // clean up readers
  SkyeTek_FreeReaders(readers, numReaders);
  SkyeTek_FreeDevices(devices, numDevices);
  return 1;
}

int main(int argc, char* argv[])
{
    DWORD id1;
    HANDLE h;
  char line[128];

  fp = fopen("sloopDebug.txt","w");

  printf("SkyeTek API Loop Example\n");
  printf("Hit return to exit\n");

    if( (h=CreateThread(NULL,0,ThreadProc,NULL,0,&id1)) == NULL )
        return FALSE;

  gets(line);

  // signal stop and wait
  isStop = true;
  WaitForSingleObject(h,10000);

  // cleanup
  CloseHandle(h);
  fclose(fp);

  printf("Done\n");
  return 0;
}
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 16:01
Le code :
  // set reader info
  printf("Found reader: %s\n", readers[0]->friendly);

me renvoie donc uniquement la première lettre.

Voici la structure SKYETEK_READER :

typedef struct SKYETEK_READER
{
  LPSKYETEK_ID              id;
  TCHAR                      model[128];
  TCHAR                      serialNumber[128];
  TCHAR                      firmware[128];
  TCHAR                      manufacturer[128];
  TCHAR                      rid[128];
  TCHAR                      readerName[128];
  TCHAR                      friendly[256];
  unsigned char             isBootload;
  unsigned char             sendRID;
  LPSKYETEK_PROTOCOL        lpProtocol;
  LPSKYETEK_DEVICE          lpDevice;
  void                      *user;
  void                      *internal;
} SKYETEK_READER, *LPSKYETEK_READER;
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 16:04
Cela ne ressemble pas à de l'UNICODE !
Pour en revenir à la structure qui pose problème, elle est décrite comment et renseignée par qui ?

Jean-François
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 16:13
Par contre la structure SKYETEK_READER est compatible UNICODE avec ces TCHAR !
Tout cela donne vraiment à penser que l'API est compilée en mode UNICODE, vu ce qu'elle retourne dans la structure readers. En ajoutant le #define UNICODE tout au début ça ne change rien ?

Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 16:16
Non si j'ajoute un #define UNICODE dans l'en tête du fichier sloop, ca ne change rien :(
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
9 avril 2008 à 16:21
En cherchant des infos sur Google je tombe sur un autre post ici qui parle du même programme mais pas de ce problème ! Peut-être pourra-t'il donner des infos sur sa façon de compiler ?

http://www.cppfrance.com/infomsg_RFID-SKYETEK-DEVELOPER-KIT_1067874.aspx

Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
9 avril 2008 à 16:25
Oui merci, j'étais tombé aussi dessus en faisant mes recherches, mais aucune info susceptible de m'aider... Quelle galère...
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
9 avril 2008 à 18:09
Salut,

Pour compiler en unicode, il faut definir UNICODE et _UNICODE, et si
possible c'est quand même mieux de faire ca dans les options du compilo
plutot que dans le code, comme ça, aucun probleme et tu ne te
retrouvera pas avec un cpp compilé en ansi et un en unicode.

A noter qu'il existe aussi plein de macro pratiques pour faire un code
qui compile en unicode ou en ansi au choix: TCHAR, TEXT, LPTSTR,
_tcslen, etc.
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
10 avril 2008 à 11:16
Voilà un petit exemple de programme qui convertit une chaîne UNICODE en ASCII :

#define UNICODE
#include <stdio.h>
void main()
{
   char  *szA =  "Hello ASCII\n";   // chaîne ASCII
   WCHAR *szW = L"Hello UNICODE\n"; // chaîne UNICODE

   // --- Visualiser les 2 versions
   printf(szA);
   wprintf(szW);




   // --- Convertir la chaîne UNICODE en ASCII

   char szWA[100];
   WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK
                      ,szW,wcslen(szW)
                      ,szWA,100
                      ,NULL,NULL);
   printf(szWA);
}


Ce qui donne :

Hello ASCII    chaîne ASCII
Hello UNICODE  chaîne UNICODE
Hello UNICODE  chaîne UNICODE convertie en ASCII

Peut-être faire un test en utilisant cette conversion sur readers[0]->friendly (à la place de szW) pour voir si ça corrige (localement) le problème ?

   // set reader info
 
  char szWA[100];
   WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK
                      ,readers[0]->friendly,wcslen(readers[0]->friendly)
                      ,szWA,100
                      ,NULL,NULL);
   printf("Found reader: %s\n",szWA);



Jean-François
0
Vinalys21 Messages postés 17 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 11 avril 2008
10 avril 2008 à 14:15
Alors la j'avoue que je suis bluffé, ça marche niquel. Un grand merci ! Donc si j'ai bien compris cette fonction permet d' encoder une chaine UNICODE en ASCII? Il faudrait  donc que je compile en ASCII ? Je suis entrain de regarder comment passer ca en option au compilateur
0
Rejoignez-nous