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 :

passage de paramètres


Sujet :

C

  1. #1
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut passage de paramètres
    Bonjour,

    je travaille avec Borland C++ 5.0 et j'ai un petit problème d'effet de bord du apparemment à un passage de paramètre.

    Je veux travailler sur des bytes et modifier et tester des bits.
    Je joins un bout de programme qui met en évidence mon problème.
    La fonction bclr fait un "bit clear" du bit N°n de octet.
    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
    #include <stdio.h>
    #define byte unsigned char
     
    void bclr(byte n, byte &octet);
     
    void main(void) {
    byte data = 255;
    byte num;
     
       printf("\n data = %d",data);
       bclr(5,data);
       scanf("%hd",&num);
       printf("\n data = %d",data);
    }
     
    void bclr(byte n, byte &octet) {
        octet = octet & (~(0x01 << n));
    }
    Le problème: avant le scanf, data vaut bien 0xdf et au retour, si je rentre 7 pour num, data vaut maintenant 0 et num = 7

    Si maintenant je rentre 260 pour num, num vaut 4 et data vaut 1. sachant que 260 = 0x104, il apparait que bien que je manipule des unsigned char, le scan remonte une valeur sur 16 bits qui écrase donc data.

    Si je ne fais pas l'appel de la fonction bclr, tout fonctionne bien.

    Pouvez-vous m'expliquer ou je me suis planté?

    Merci

  2. #2
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Salut,

    Citation Envoyé par jackk
    Pouvez-vous m'expliquer ou je me suis planté?
    Non, personnellement, je n'y connais pas grand chose à printf et scanf.

    Pourquoi n'utilises-tu pas les opérateurs de flux de la std : cin et cout ?


    [EDIT]Après une recherche rapide dans la doc de scanf, je m'apperçois que %d ne doit pas être utilisé pour les données larges de 1 byte, c'est donc normal que cela déborde.

    Utilise plutot %c ou %C.

    Note : tu n'aurais pas eu le problème avec les opérateurs de flux de la stl dont les paramètres sont typés.
    [/EDIT]

  3. #3
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    merci pour ta réponse

    Pourquoi n'utilises-tu pas les opérateurs de flux de la std : cin et cout ?
    Parce que j'utilise le C avec des élèves en électronique et que la programmation objet sort un peu de la formation.

    Après une recherche rapide dans la doc de scanf, je m'apperçois que %d ne doit pas être utilisé pour les données larges de 1 byte, c'est donc normal que cela déborde.
    je pensais que le "scanf("%hd",&num);" résolvait le problème (le hd devant normalement traiter des short int).

    Et pourquoi, le scanf fonctionne-t-il sans l'appel de bclr?

    A+

  4. #4
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par jackk
    Parce que j'utilise le C avec des élèves en électronique et que la programmation objet sort un peu de la formation.
    Dans ce cas, tu trouveras de meilleurs conseils sur le forum C.
    Je ne m'y connais franchement pas en scanf.

    Bonne chance.

  5. #5
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Peut-être en effet.

    J'ai posté en C++ car j'utilise une syntaxe de passage de paramètre par adresse qui n'existe pas en C.

    Avec la syntaxe classique, le problème est le même.

    Si je n'obtiens pas de réponse, je posterai dans le forum C.

    A moi qu'un modérateur ne passe par là et déplace ce fil dans le forum C car je suppose qu'il n'est pas très bien vu de poster la même chose dans 2 forums.

    A+

  6. #6
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 527
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 527
    Par défaut
    s'il ya un problème avec scanf c'est que le format n'est pas bon...
    c'est certain qu'avec cin c'est moins se casser la tête

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    J'ai posté en C++ car j'utilise une syntaxe de passage de paramètre par adresse qui n'existe pas en C.
    Les pros du scanf ne sont clairement pas ici. Comme le problème ne semble pas lié au passage par référence et que tout le reste est du C, je déplace vers le forum approprié.

    Mais à mon avis la réponse est la suivante : il n'y a pas de formatteur pour unsigned char (sous forme décimale), il va falloir utiliser un autre type

  8. #8
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Le specificateur de format hd signifie short int. Pour un unsigned int, c'est u. Cf. man scanf() [qui est une fonction dangeureuse à apprendre à des débutants].
    Edit: oups, pas vu que tu utilises unsigned char. Dans ce cas, essaie le specificateur c -- mais sans garanties.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Dans le monde merveilleux de scanf(), il me semble bien que "%c" signifie une chaîne
    "%1c" devrait convenir.
    Ou tout simplement getchar().

    Je crois que scanf() n'offre aucun moyen de saisir directment un nombre en décimal dans un char. Il faut au minimum passer par un short.
    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
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Médinoc
    Dans le monde merveilleux de scanf(), il me semble bien que "%c" signifie une chaîne
    Non un caractere pas une chaine. Une chaine c'est %s

  11. #11
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    Par défaut
    e pensais que le "scanf("%hd",&num);" résolvait le problème (le hd devant normalement traiter des short int).
    -> %d pour du décimal
    -> %x pour de l'hexa

    -> %hd, j'ai du mal à me rappeler ? Quelle est cette chose étrange ?

    -> Pouvez-vous essayer %d ?

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par jackk
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void bclr(byte n, byte &octet);
    Heu, si tu fais du C++, tu t'es trompé de forum...

    En supposant que tu fais du C, ton code commenté et corrigé :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    #include <stdio.h>
     
    /* -ed- ajoute pour controles... */
    #include <assert.h>
     
    /* -ed-
    #define byte unsigned char
     
    Preferer le style 'typedef'. En fait, probablement inutile...
    */
     
    /* -ed-
    Il n'est pas utile de separer le prototype
           si la fonction est dans la meme unite de compilation.
           Il suffit de respecter le principe 'definir avant d'utiliser'.
     
    void bclr(byte n, byte &octet);
    */
     
    /* -ed- Deplace...
    void bclr(byte n, byte *octet) {
        octet = octet & (~(0x01 << n));
    }
     
    byte etant un type char, cette fonction gerere du code unutilement
    complexe. En effet, en C, les parametres de type char sont automatiquement
    convertis en int. Il est donc inutile de perdre son temps a utiliser char,
    car ca ne fait qu'ajouter du code inutile.
     
    De plus, il serait bien plus rentable d'utiliser le retour de la fonction...
     
    */
    unsigned bclr (unsigned octet, unsigned n)
    {
       /* -ed- simple precaution. La methode est barbare mais efficace... */
       assert (n < 8);
       return octet & (~(0x01u << n));
    }
     
    /* -ed-
    void main(void)
     
    main() retourne int. Toujours...
    */
    int main (void)
    {
       unsigned data = 255;
       unsigned num;
     
    /* -ed- un affichage en hexadecimal est plus clair quand on manipule
    des bits...
     
    La place du '\n' est en fon de ligne, pas en debut...
    */
       printf ("data = %02X\n", data);
     
    /* -ed- la logique de ce code est absurde...
       bclr(5,data);
       scanf("%hd",&num);
       printf("\n data = %d",data);
    */
     
       scanf ("%u", &num);
       /* -ed- scanf () est une fonction difficile a utiliser correctement.
          Il faudrait traiter les cas d'erreur...
     
          Le C, n'est pas un langage de debutant. Trop de subtilites...
        */
     
    /* -ed- il faudrait s'assurer qu'on ne va pas decaler de plus 7 ... */
       data = bclr (data, num);
       printf ("data = %02X\n", data);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    data = FF
    5
    data = DF
     
    Press ENTER to continue.
    Tu devrais méditer là-dessus :

    http://emmanuel-delahaye.developpez..../ed/inc/bits.h

    Evidemment, c'est plutôt une approche industrielle...

  13. #13
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par gl
    Non un caractere pas une chaine. Une chaine c'est %s
    Disons que %c est utilisé pour une suite de caractère (espaces compris). %s est utilisé pour une chaine (espaces négligés par défauts, chaine terminée par '\0').

  14. #14
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par DaZumba
    Disons que %c est utilisé pour une suite de caractère (espaces compris). %s est utilisé pour une chaine (espaces négligés par défauts, chaine terminée par '\0').
    Non, %c c'est pour un caractere. Si on attends une suite de caractere, il faut le preciser.

    Citation Envoyé par n1124
    Matches a sequence of characters of exactly the number specified by the field
    width (1 if no field width is present in the directive).246)

  15. #15
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par gl
    Non, %c c'est pour un caractere. Si on attends une suite de caractere, il faut le preciser.
    Ooky dooky -- merci pour la précision. A force de ne jamais utiliser scanf(), on finit par ne pas la connaître, cette fonction...

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par DaZumba
    A force de ne jamais utiliser scanf(), on finit par ne pas la connaître, cette fonction...
    Approche tres saine du probleme a laquelle j'adhere egalement

Discussions similaires

  1. [Forms]Passage de paramètre entre Forms et Reports
    Par jack554 dans le forum Reports
    Réponses: 4
    Dernier message: 30/03/2004, 13h58
  2. probleme lors du passage de paramètre
    Par maxmj dans le forum ASP
    Réponses: 4
    Dernier message: 18/11/2003, 00h15
  3. [XSL] Passage de paramètres à un template
    Par pantin dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/06/2003, 13h28
  4. passage de paramètres
    Par pram dans le forum XMLRAD
    Réponses: 5
    Dernier message: 18/02/2003, 17h28
  5. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 19h47

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