Un tableau qui se remplit avec des'\0' entre chaque caractère ? [Résolu]

Signaler
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008
-
cs_jfrancois
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009
-
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

Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

Il faudrait donc que l'encodage de mes chaines de caractères soit de type ASCII ??
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

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...
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

C'est un exemple qui compile en UNICODE ?

Jean-François
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

Comment puis je le savoir?
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

Rien de tout ca. Y'a t'il possibilité de mettre une #define ASCII alors? :D
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

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;
}
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

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;
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

Non si j'ajoute un #define UNICODE dans l'en tête du fichier sloop, ca ne change rien :(
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

Oui merci, j'étais tombé aussi dessus en faisant mes recherches, mais aucune info susceptible de m'aider... Quelle galère...
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
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.
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

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
Messages postés
17
Date d'inscription
jeudi 22 novembre 2007
Statut
Membre
Dernière intervention
11 avril 2008

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
1 2