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

Windows Discussion :

caster un int en char sur taille fixe


Sujet :

Windows

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut caster un int en char sur taille fixe
    Bonjour à tous,

    Je vais essayer de vous expliquer ce que je cherche à faire, et pourquoi je cherche à le faire.
    Actuellement j'utilise sprintf pour transformer des long long int dans une chaine de caractère en séparant les 2 nombres par une virgule.
    Seulement le problème est le suivant: si mon long long int contient le nombre "450" par exemple (je sais que cela tient dans un int mais cette variable est amené à contenir des nombres > 4 milliards).
    En mettant dans le tableau cela va prendre 3 "cases", donc 3 octets,je peux voir ça avec strlen().
    Mais pour mon application je dois savoir si j'ai reçu assez d'informations sur la socket pour pouvoir faire le traitement.

    Et pour faire cela je dois avoir la première "case" de mon paquet qui contient la taille du reste des données. Et cette case doit avoir une taille fixe (ne contiendra pas une valeur > a celle que peut contenir un int) de façon à ce que je puisse regarder si la taille des données accessibles sur la socket est au moins supérieurs à cette taille fixe. Si c'est le cas je suis capable de récupérer la taille de ce qui va suivre, et vérifier ensuite que j'ai reçu assez de données pour faire le traitement, sinon j'attends pour revérifier.

    D'ailleurs cette fonction sprintf() n'est pas dérangé si je lui met un char tab[3] et que je cherche à mettre dedans un nombre comme "599400", alors qu'il devrait y avoir un débordement du tableau.

    Du coup je ne sais vraiment pas quoi faire.
    Aujourd'hui ça marche parce que la taille des données envoyées pour l'initialisation est faible donc je les reçois quasi à coup sûr, mais je préfère assurer mes arrières, et de plus j'en aurais besoin pour la suite pour de la messagerie instantanée (on ne peux pas afficher qu'un morceau du message).

    EDIT: Ce code ne veut pas fonctionner, mais fonctionne si je met juste un char, mais dans ce cas pas possible de mettre un nombre > 255...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char c[2] = static_cast<char[2]>( i );
    Merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Pour sérialiser un entier sur des chars, afin d'éviter les problèmes d'endianness, on les écrit octets par octets.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int ecrire_int(char *buf, size_t taille, size_t *pIndex, int valeur)
    {
    	int i;
    	for(i=0 ; i<4 ; i++)
    	{
    		if((*pIndex) >= taille)
    			return -1;
    		buf[*pIndex] =  (char)((valeur & 0xFF000000)>>24);
    		(*pIndex)++;
    		valeur <<= 8;
    	}
    	return 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.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Bonjour,

    Merci pour ta réponse, mais je ne comprends pas vraiment le code...
    Notament avec le *pIndex. Est-il possible que tu m'expliques ce qui est fait avec un exemple sur un int qui vaut "6800" par exemple et qui soit codé sur mis sur 8 octets dans un tableau?

    Merci d'avoir pris le temps de répondre

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void UneFonction(void)
    {
    	char buffer[256];
    	size_t index = 0;
    	ecrire_int(buffer, sizeof buffer, &index, 6800);
    	/*Maintenant, le nombre 6800 a été écrit en big-endian dans
    	  les quatre premiers octets du buffer, et index vaut 4.*/
    	ecrire_int(buffer, sizeof buffer, &index, 42);
    	ecrire_int(buffer, sizeof buffer, &index, 129987);
    	/*Maintenant, index vaut 12.*/
    }
    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.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Je vois maintenant comment utiliser la fonction, mais cela ne semble pas fonctionner.
    La valeur de index vaut bien 12 quand je l'affiche à la fin, par contre buffer est vide (cout<<buffer<<endl).

    De plus je n'ai pas vraiment compris le fonctionnement de ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if((*pIndex) >= taille)
    			return -1;
    		buf[*pIndex] =  (char)((valeur & 0xFF000000)>>24);
    		(*pIndex)++;
    		valeur <<= 8;
    Merci

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    buffer est un tableau d'octets bruts, tu ne peux donc pas l'afficher directement avec cout.
    Mais tu peux l'afficher ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cout << hex << setfill('0');
    for(size_t i=0 ; i<index ; i++)
    {
    	unsigned char uc = buffer[i];
    	cout << setw(2) << (int)uc) << ' ';
    }
    cout << endl;
    Le code que tu as copié:
    • Le test permet de vérifier qu'on ne dépasse pas de la taille du buffer
    • Si on va dépasser, on retourne -1 à la place.
    • La ligne suivante place l'octet supérieur du int (en supposant qu'un int fasse 32 bits) dans le buffer. Résultat, indépendamment de l'endianness de la machine, le int est toujours écrit en big-endian (poids fort en premier).
    • La ligne suivante incrémente l'index
    • Et la dernière décale la valeur vers la gauche pour mettre l'octet suivant en poids fort.
    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.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    J'avais a peu près compris l'idée qui était de se déplacer dans le tableau pour écrire "case par case", mais pourquoi faire du code hexadécimal.

    Et justement le dernier code posté me retourne de l'hexa, comment puis-je le récupérer en int?
    J'avoue que j'ai encore beaucoup de mal avec ces concepts

    Merci à toi

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Des données brutes, traditionnellement on les affiche en hexa.
    Si tu veux relire le int, il te faut faire la procédure inverse :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int lire_int(char const *buf, size_t taille, size_t *pIndex, int *pValeur)
    {
    	int i, valeur=0;
    	for(i=0 ; i<4 ; i++)
    	{
    		if((*pIndex) >= taille)
    			return -1;
    		valeur <<= 8;
    		valeur |= (unsigned char)(buf[*pIndex]);
    		(*pIndex)++;
    	}
    	*pValeur = valeur;
    	return 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.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Avec ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    index = 0;
        int mavaleur;
        lire_int(buffer, sizeof(buffer), &index, &mavaleur);
    	cout<<"valeur int= "<<mavaleur<<endl;
    J'obtiens valeur int = 1a90, ce qui n'est pas vraiment ce que l'on attends.
    De plus peux tu me dire comment est codé un int en mémoire (sur 4 octets) parce que moi je voyais ça comme une succession de 1 et de 0 (du binaire quoi) qui permet d'aller jusqu'à une valeur décimale de 2 milliard et quelques.

    Merci

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Il faut remettre cout en décimal, pour commencer.
    PS: 0x1A90 est égal à 6800, donc c'est parfaitement ce qu'on attendait.
    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.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Bonsoir,

    J'ai quasiment compris ton code, pour ça j'ai du réécrire des morceaux pour me démontrer le fonctionnement, et résultat cela fonctionne aussi donc j'en déduis que j'ai bien compris le fonctionnement.

    Je crois que je n'aurais vraiment pas su sortir un tel code par moi-même.
    Un mot: merci

    EDIT: J'en profite: Est ce que tu peux m'expliquer le fonctionnement exact de tes surcharges d'opérateur dans la fonction lire_int?
    Merci bien

    Bonne soirée

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Il n'y a aucune surcharge d'opérateur, c'est du C pur.
    C'est le vrai opérateur de décalage de bit <<, >>, <<= et >>=, et non pas les opérateurs surchargés pour les flux C++.
    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.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Bonjour,

    Et pour celui-ci: |= ?
    C'est surtout cette ligne qui me pose problème.
    Une autre question le décalage de bit: Quand on décale de 8 vers la gauche est ce que l'on retrouve nos 8 bits tout à gauche (jeu su serpent qui sort d'un coté et ressort de l'autre?) ou alors c'est remplacé par des 0?

    Merci bien

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    a |= b correspond à a = a | b.
    Le symbole | représente le OU bit-à-bit, à ne pas confondre avec || qui représente le OU booléen:
    • 2 | 4 donne 6
    • 2 || 4 donne 1.


    Le décalage de bits n'est pas une rotation. Par contre, il me semble que la norme ne garantit pas ce qui est inséré à gauche dans le cas d'une rotation vers la droite de nombre non-signé: Soit c'est des zéros, soit le bit de poids fort est dupliqué.
    • Si je fais a = 0x12345678 << 8 (décalage vers la gauche), a vaudra 0x34567800.
    • Si je fais a = 0xFEDCBA98 >> 8 (décalage vers la droite), a vaudra 0x00FEDCBA ou 0xFFFEDCBA. Si je précise que la constante est non-signée (en rajoutant un u derrière), alors ce sera forcément la première solution).

    Je me souviens que les processeurs 68000 ont deux instructions séparées pour le décalage à droite (et aussi à gauche, mais les deux sont identiques).
    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.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2008
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 48
    Points : 17
    Points
    17
    Par défaut
    Ok merci bien pour les explications. Je pense qu'il faudrait que je m'ecrive sur une feuille une exemple avec un tableau et le OU | parce que j'ai encore du mal à voir les opération (par contre ecrire_int c'est tout bon).

    Merci encore pour ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. pointeur sur tableau de taille fixe
    Par stracoma dans le forum C++
    Réponses: 5
    Dernier message: 05/03/2015, 14h54
  2. [CSS 3] Bandeau large sur div de taille fixe
    Par bannik dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 03/12/2013, 19h29
  3. Réponses: 10
    Dernier message: 14/01/2013, 14h19
  4. scroll (positionnement) sur une liste dans DIV de taille fixe
    Par Heretic dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 11/05/2010, 16h26
  5. [SQL] Convertir un champ INT en CHAR dans un SELECT ?
    Par webtheque dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/03/2005, 14h45

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