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 :

comportement non attendu avec memcpy


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 131
    Par défaut comportement non attendu avec memcpy
    Bonjour,

    J aimerai copier une variable dans une chaine de caractere.

    Par exemple copier l entier int i = 123 dans la chaine de caractere char *s.
    Lorsque je dis copier, j aimerai que les 4 octets de i soient recopier dans les 4 premier octets de s.

    Voici mon code :

    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
     
          1 #include <stdio.h>
          2 #include <stdlib.h>
          3 #include <string.h>
          4
          5
          6
          7 int main(void)
          8 {
          9     char *s = calloc(5, sizeof(char)); // j alloue la taille d'un int + 1 pour le caractere de fin de chaine.
         10     const int i = 134423;
         11
         12     memcpy(s, &i, 4);
         13     printf("%d\n", *s);   // j affiche les 4 premier octets.
         14
         15     return 0;
         16 }
    Cela affiche :

    Ou ai je puis faire une erreur ???

    Merci

  2. #2
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Que souhaite tu réaliser?

    Si tu veux convertir un int en char *, il existe d'autres solutions plus propres.

  3. #3
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Oh my god...

    1) pour ecrire un entier dans une chaine, c'est
    sprintf (zone, "%d", entier)
    2) pas besoin d'allocation dynamique, un tableau de caractere de taille fixe suffit
    3) il manque le free

  4. #4
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Au fait, arretez de croire que "char *" = "chaine de caractere"
    On est pas en VB, ni PHP
    Il faut raisonner par "zones memoire"

  5. #5
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *s = calloc(5, sizeof(char));
    plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *s = calloc(sizeof(int)+1, sizeof(char));
    et:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(s, &i, sizeof(int));
    pour la portabilité.

  6. #6
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    1) pour ecrire un entier dans une chaine, c'est
    sprintf (zone, "%d", entier)
    Pas ici:
    Lorsque je dis copier, j aimerai que les 4 octets de i soient recopier dans les 4 premier octets de s.

  7. #7
    Membre expérimenté Avatar de Pikwik
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 237
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("%d\n", *s);   // j affiche les 4 premier octets.
    Pourquoi "*s" ?

  8. #8
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Bon et pour repondre au probleme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d\n", *((int *)s));
    sauf que c'est debile de passer par un char *, si tu veux l'utiliser comme un int *

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 131
    Par défaut
    Citation Envoyé par Gruik
    1) pour ecrire un entier dans une chaine, c'est
    sprintf (zone, "%d", entier)
    Ce n est pas ce que je veux faire.
    J ai envoie de copier les 4 bytes de l entier dans les 4 byte de s.
    Or avec sprintf la taille de s est pas egale a 4 mais egale au nombre de chiffre qu a l entier i.

    par exemple i = 255

    alors i (en bas 2) = 00000000 00000000 0000000 11111111

    j ai envie que
    s[0] (en base 2) = 00000000
    s[1] (en base 2) = 00000000
    s[2] (en base 2) = 00000000
    s[3] (en base 2) = 11111111

    Citation Envoyé par Gruik
    2) pas besoin d'allocation dynamique, un tableau de caractere de taille fixe suffit
    Certes, mais ce ce que je fais n est pas faux non plus.

    Citation Envoyé par Gruik
    3) il manque le free
    Alors la je n ai rien a redire .

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 131
    Par défaut
    tout a fait ca je doit envoyer sur un reseau plusieurs information.
    Ce que je voulais faire c etait de creer une chaine de caracteres, comme ca je met les informations voulues, .... et j envoie

  11. #11
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Citation Envoyé par berg
    tout a fait ca je doit envoyer sur un reseau plusieurs information.
    Ce que je voulais faire c etait de creer une chaine de caracteres, comme ca je met les informations voulues, .... et j envoie
    Dans ce cas, il faut vraiment faire attention à l'ordre des octets quand on envoie et reconstitue l'entier...
    Yavait un fonction dans la librairie reseau pour convertir big endian en little endian et vice versa.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    131
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 131
    Par défaut
    ok merci pour voter aide !!!


  13. #13
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Dans ce cas la...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int a = 0x7f00ff80;
    char * s = (char *)&a;
    A priori, ça devrait donner
    s[0] (en base 2) = 01111111
    s[1] (en base 2) = 00000000
    s[2] (en base 2) = 11111111
    s[3] (en base 2) = 10000000

    ..mais ya des histoires de big endian / little endian, y se peut que l'ordre soit l'inverse..

Discussions similaires

  1. Div avec des dimensions non attendues
    Par Amerzone38 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 22/03/2010, 10h54
  2. [JButton] Background non coloré avec LnF Windows
    Par leminipouce dans le forum Composants
    Réponses: 7
    Dernier message: 03/10/2005, 13h48
  3. Réponses: 5
    Dernier message: 02/09/2005, 12h47
  4. Réponses: 5
    Dernier message: 12/05/2005, 10h49
  5. Réponses: 4
    Dernier message: 07/12/2002, 15h24

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