IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Conversion d'une variable


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 49
    Points : 16
    Points
    16
    Par défaut Conversion d'une variable
    Bonjour,
    je vais essayé d'être clair.

    J'utilise des fonctions ou les types (int, char ect sont redéfinis).
    exemple : typedef unsigned char UINT8;

    J'ai une fonction qui demande un code, j'ai donc UINT8 Code[4];
    Si je fais un cin>>Code;
    Et que j'envoi Code dans ma fonction, par de soucis.
    Par contre maintenant quand je passes par une socket.
    La fonction recv() (reception qui permet de recevoir le code via une socket) renvoi un char*.
    J'ai tenter de transformer ce char* en UINT8, par exemple avec un cast, la valeur est bonne quand je l'affiche mais si je l'utilise dans ma fonction, la fonction retourne une erreur (en gros le code "1234" n'est pas égal au code "1234" que je devrais envoyer a la fonction).

    Je ne vois pas comment convertir proprement mon char*.
    J'espère que j'ai été assez clair, merci de votre aide.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par johntayback Voir le message
    Bonjour,
    je vais essayé d'être clair.

    J'utilise des fonctions ou les types (int, char ect sont redéfinis).
    exemple : typedef unsigned char UINT8;

    J'ai une fonction qui demande un code, j'ai donc UINT8 Code[4];
    Si je fais un cin>>Code;
    Et que j'envoi Code dans ma fonction, par de soucis.
    Par contre maintenant quand je passes par une socket.
    La fonction recv() (reception qui permet de recevoir le code via une socket) renvoi un char*.
    J'ai tenter de transformer ce char* en UINT8, par exemple avec un cast, la valeur est bonne quand je l'affiche mais si je l'utilise dans ma fonction, la fonction retourne une erreur (en gros le code "1234" n'est pas égal au code "1234" que je devrais envoyer a la fonction).

    Je ne vois pas comment convertir proprement mon char*.
    J'espère que j'ai été assez clair, merci de votre aide.
    Bonjour,
    Pas trop

    recv remplit le buffer que tu lui fournit avec les octets reçus. A ma connaissance, il ne renvoie pas de buffer ?

    Une piste : n'aurais-tu pas un problème d'endianess ?

    Autrement, pourrais-tu nous montrer un code minimal qui reproduise ton problème ?

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Le fait que recv() demande un char* est un bug de l'API Windows de toute façon.
    Le plus simple est d'utiliser systématiquement un reinterpret_cast dessus, ou bien de faire un wrappeur avec le prototype correct:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ssize_t goodrecv(SOCKET socket, void *buffer, size_t length, int flags)
    {
    	int length32 = static_cast<int>(length);
    	if(length32 < 0 || static_cast<size_t>(length32) != length)
    		throw std::exception("La version Windows ne supporte pas une taille supérieure à 2**19");
    	int ret = recv(socket, static_cast<char*>(buffer), length32, flags);
    	return static_cast<ssize_t>(ret);
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Je pense qu'il y a une subtilité qui m'échappe dans le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int length32 = static_cast<int>(length);
    if(length32 < 0 || static_cast<size_t>(length32) != length)
    Qul est l'intérêt de ce double static_cast ?

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Un size_t fait la taille d'un pointeur, qui peut être 64 bits.
    Un int n'en fait que 32.
    Donc, on vérifie si la valeur du paramètre length tient dans un int, vu que la version Windows de recv() n'accepte pas plus grand.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 49
    Points : 16
    Points
    16
    Par défaut rep
    Bonjour, merci pour vos réponses.

    J'arrive finalement à faire ce que je voulais, même si ce n'est pas propre du tout.

    Je précise que le type UNIT8 est défini de cette façon : typedef unsigned char UINT8;

    Ma fonction pour la réception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    char* Serveur::Reception(void)
    {
    	char recvbuf[512];
        int recvbuflen = 512;
    	int fin=FALSE;
     
     
    	while(!fin)
    	{
    		if(recv((SOCKET)*pt_Nouveau_Socket_Serveur,recvbuf,recvbuflen,0))
    		{
    			fin=TRUE;
    		}
    	}
     
     
    	return(recvbuf);
    }
    En Variable globale j'ai : UINT8 CodePorteur[4];

    Dans mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	char* cpPorteur;
    	cpPorteur=objServeur->Reception();//Attente de l'envoi du Code Porteur (saisie sous Flash)
    	convCodePorteur(cpPorteur);
    La fonction convCodePorteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void convCodePorteur(char* CoPorteur)
    {
    	for(int i=0; i<=3; i++)
    		CodePorteur[i]=CoPorteur[i];
    }
    Voila c'est pas très joli, mais sa fonctionne en attendant de trouver mieux.
    Médinoc je n'ai pas très bien compris ce que tu as posté, ça pourrait être utile dans mon cas?

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Citation Envoyé par johntayback Voir le message
    Voila c'est pas très joli, mais sa fonctionne en attendant de trouver mieux.
    Tu as de la chance car :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char* Serveur::Reception(void)
    {
    	char recvbuf[512];
    [...] 
    	return(recvbuf);
    }
    Tu retourne l'adresse d'une variable locale de la pile, ce qui est une erreur.
    3 solutions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char* Serveur::Reception(void)
    {
    	char *recvbuf = new char[512];
    [...] 
    	return(recvbuf);
    }
    // puis :
    	char* cpPorteur;
    	cpPorteur=objServeur->Reception();//Attente de l'envoi du Code Porteur (saisie sous Flash)
    	convCodePorteur(cpPorteur);
            delete []cpPorteur;
    Remarque : cette solution présentée ici simplement devrait en fait tenir compte des problématiques des pointeurs nus et utiliser ou un pointeur intelligent ou gérer cette problématique.

    2ème solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void Serveur::Reception(char*recvbuf, size_t recvbuflen)
    {
    [...] 
    }
    //et :
            const size_t recvbuflen = 512
    	char cpPorteur[recvbuflen];
    	cpPorteur=objServeur->Reception(cpPorteur,recvbuflen);//Attente de l'envoi du Code Porteur (saisie sous Flash)
    	convCodePorteur(cpPorteur);
    3ème solution (C++) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    void Serveur::Reception(std::vector<unsigned char> &recvbuf)
    {
    	int fin=FALSE;
     
     
    	while(!fin)
    	{
    		if(recv((SOCKET)*pt_Nouveau_Socket_Serveur,&(recvbuf[0]),recvbuf.size(),0))
    		{
    			fin=TRUE;
    		}
    	}
     
    }
    // et :
            const size_t recvbuflen = 512
    	std::vector<unsigned char> cpPorteur(recvbuflen);
    	cpPorteur=objServeur->Reception(cpPorteur);//Attente de l'envoi du Code Porteur (saisie sous Flash)
    	convCodePorteur(cpPorteur);
     
    // et 
    void convCodePorteur(std::vector<unsigned char> const & CoPorteur)
    {
    	for(int i=0; i<=3; i++)
    		CodePorteur[i]=CoPorteur[i];
    }

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 49
    Points : 16
    Points
    16
    Par défaut rep
    Merci pour tes remarques 3DArchi.

    J'ai fait les modifications présentés dans ta première solution.
    Pas de changement dans le fonctionnement de mon programme, mais sa m'évitera peut être des problèmes pour la suite.

    J'ai encore un problème sur ces changements de type.
    J'ai maintenant une fonction d'envoi, qui fonctionne très bien si je lui donne en paramètre un char*et la réception ce fait bien sur Flash.

    Cependant les variables que je dois envoyées sont de type UINT8.
    J'ai essayé une fonction de conversion, mais j'ai une erreur qui arrête l'exécution de mon programme.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    convDonneeEnvoi(sizeof(InfosPorteur.NomPatronym),InfosPorteur.NomPatronym)
    //InfosPorteur.NomPatronym est une variable de type UINT8 de taille max [27].
    Ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /* Variable globale */
    char* EnvoiFlash;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void convDonneeEnvoi(int taille,PUINT8 DonneeEnvoi)
    {
    int i=0;
    		for (i=0; i <= taille; i++)
    	{
    		EnvoiFlash[i]=DonneeEnvoi[i];
    	}
    EnvoiFlash[i+1]='\0';
    }
    Voila, à l'exécution de cette fonction le programme s'arrête, surement un problème au niveau des pointeurs.
    Si vous avez une idée.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ce que j'ai posté, c'était juste pour avoir un recv() plus respectueux des standards.

    Un recv() avec lequel tu peux tout simplement faire:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    tailleRecue = goodrecv(leSocket, leTableauDeUINT8, laTaille, 0);
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je ne sais pas quelle est la taille de EnvoiFlash. L'erreur est-elle là ?
    En revanche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (i=0; i <= taille; i++)
    {
       EnvoiFlash[i]=DonneeEnvoi[i];
    }
    Te fais adressé DonneeEnvoi[taille] ce qui est une erreur mais ne devrait pas à priori provoquer le plantage.

    Enfin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sizeof(InfosPorteur.NomPatronym) = sizeof(InfosPorteur.NomPatronym[0]*NbrElements(InfosPorteur.NomPatronym)
    Avec ton UINT8, ça ne fait peut être pas de problème, mais en général, le nombre d'éléments d'un tableau peut se récupérer en tenant compte de ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sizeof(InfosPorteur.NomPatronym)/sizeof(InfosPorteur.NomPatronym[0]);
    Sous réserve bien sur que InfosPorteur.NomPatronym est un tableau statique (NomPatronym[taille]) et non un tableau dynamique (NomPatronym = new Type[taille]).

Discussions similaires

  1. Conversion d'une variable string en tableau
    Par kyino dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 27/02/2015, 14h14
  2. Réponses: 3
    Dernier message: 07/02/2013, 15h39
  3. Conversion d'une variable string en BSTR
    Par thibthib71 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 20/09/2012, 12h52
  4. conversion d'une variable sous CVI
    Par Invité(e) dans le forum C
    Réponses: 0
    Dernier message: 26/11/2009, 15h17
  5. Conversion d'une variable en string
    Par yamino dans le forum Débuter
    Réponses: 6
    Dernier message: 31/03/2008, 00h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo