langage C : problème avec variable globale et scanf
Répondre à la discussion
Affichage des résultats 1 à 19 sur 19

langage C : problème avec variable globale et scanf



  1. #1
    invitedba13d1f

    langage C : problème avec variable globale et scanf


    ------

    Bonsoir,

    Voici le début d'une application qui a pour but de tester une fonction qui convertit un caractère en valeur hexadécimale rentré au clavier en valeur binaire.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int x3, x2, x1, x0 ;
    char hexa ;
    
    int main()
    {
        void hexaBinaire (void);
    
        printf("\nhexa = ");
        scanf("%c",&hexa);
        int c=0;
        while ( (c != '\n') && (c != EOF) )
        {
            ;
        }
    
        hexaBinaire() ;
    
        printf ("\n %c en valeur hexadecimale equivaut a %d%d%d%d en valeur binaire",hexa,x3,x2,x1,x0) ;
        getchar() ;
    
        return 0;
    }
    Je n'ai mis que la fonction main, le problème se posant avant l'appel à la fonction hexaBinaire.
    En mettant des printf un peu partout, j'ai remarquer que le programme se bloquait sur la ligne du scanf. On rentre le caractère désiré au clavier mais on ne passe pas à l'instruction suivante

    Je suppose que le problème vient du fait que j'utilise une variable globale mais je ne comprend pas pourquoi ça bloque

    Si quelqu'un sait ce qui pose problème, je le remercie d'avance

    -----

  2. #2
    Jean.Marc

    Re : langage C : problème avec variable globale et scanf

    Bonjour,
    Il me semble me souvenir que scanf attend une chaîne qui doit être terminée par un caractère de fin de ligne.
    Autrement dit, après avoir tapé le caractère, il faut appuyer sur Entrée.
    Jean-Marc

  3. #3
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Oui mais il ne se passe rien après avoir appuyé sur Entrée

    Je peux appuyer sur Entrée dix fois de suite après avoir tapé un caractère au clavier, il ne se passe rien !

    J'ai modifier mon code pour supprimer une variable globale qui n'était pas vraiment utile :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int x3, x2, x1, x0 ;
    
    int main()
    {
        void hexaBinaire (char hexa);
        char hexa ;
    
        printf("\nhexa = ");
        scanf("%c",&hexa);
        int c=0;
        while ( (c != '\n') && (c != EOF) )
        {
            ;
        }
    
        hexaBinaire(hexa) ;
    
        printf ("\n %c en valeur hexadecimale equivaut a %d%d%d%d en valeur binaire",hexa,x3,x2,x1,x0) ;
        getchar() ;
    
        return 0;
    }

  4. #4
    invite765732342432
    Invité

    Re : langage C : problème avec variable globale et scanf

    Tu n'as pas l'impression qu'il manque un truc dans ton while ? Genre un truc qui change la valeur de c... comme une saisie de caractère ?
    Parce que là, ça fait une belle boucle infinie...

  5. A voir en vidéo sur Futura
  6. #5
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Merci Faith
    Effectivement en retirant la boucle while du premier exemple, ça fonctionne beaucoup mieux

    Edit : J'ai oublié les getchar() dans mes conditions de fin de boucle !!
    Houla ... je crois qu'il est grand temps d'aller au dodo !

  7. #6
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Voici le code fonctionnel commenté pour ceux que ça intéresse (ce n'est pas ce qu'il y a de plus compacte mais ça marche ) :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int x3, x2, x1, x0 ;
    
    int main()
    {
        void hexaBinaire (char hexa);
        char hexa ;
    
        printf("\nhexa = ");
        scanf("%c",&hexa);
        int c=0;
        while ( (c = getchar() != '\n') && (c = getchar() != EOF) )
        {
            ;
        }
    
    
        hexaBinaire(hexa) ;
    
        printf ("\n %c en valeur hexadecimale equivaut a %d%d%d%d en valeur binaire",hexa,x3,x2,x1,x0) ;
        getchar() ;
    
        return 0;
    }
    
    void hexaBinaire (char hexa)
    {
    
        if ( hexa == ('0' + '1' + '2' + '3' + '4' + '5' + '6' + '7') )
        {
            x3 = 0;
        } else { x3 = 1; }
    
        if ( hexa == ('0' + '1' + '2' + '3' + '8' + '9' + 'A' + 'B') )
        {
            x2 = 0;
        } else { x2 = 1; }
    
        if ( hexa == ('0' + '1' + '4' + '5' + '8' + '9' + 'C' + 'D') )
        {
            x1 = 0;
        } else { x1 = 1; }
    
        if ( hexa == ('0' + '2' + '4' + '6' + '8' + 'A' + 'C' + 'E') )
        {
            x0 = 0;
        } else { x0 = 0; }
    
    
    }
    Voilà ! Merci encore de votre aide

  8. #7
    invite765732342432
    Invité

    Re : langage C : problème avec variable globale et scanf

    Citation Envoyé par gizmo2937 Voir le message
    Voilà ! Merci encore de votre aide
    Euh... c'est pas encore gagné...
    Parce que ça, c'est pas bon du tout:
    while ( (c = getchar() != '\n') && (c = getchar() != EOF) )

    Appeler 2 fois getchar() fait qu'à chaque boucle, tu lis 2 caractères, ce qui ne semble pas la meilleures des méthodes...
    et je ne parle pas de la fonction void hexaBinaire (char hexa) qui a l'air très bizarre ! Mais bon, ça avance...

  9. #8
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    En effet, après d'autres essais aujourd'hui ... ce n'est pas très fonctionnel et ça ne marche pas :'(
    Je devais vraiment être très fatigué hier soir !!

    Concernant l'emploi de :

    Code:
    while ( (c = getchar() != '\n') && (c = getchar() != EOF) )
    Voilà comment je comprend son utilité :
    Sans ce while, si je fais appel à un deuxième scanf (ou getchar() ), il sera inutilisable. Le caractère '\n' sera assigné à l'adresse indiqué dans mon scanf.

    Cette boucle me permet de "supprimer" le caractère '\n' de mes prochains appels à scanf ou getchar().


    A priori je peux supprimer le deuxième getchar() et ne pas inclure EOF.

    Pour la fonction hexaBinaire:

    Comme son nom l'indique, je souhaite convertir une valeur héxadécimale sur 4 bits.
    Voici le début du tableau de conversion :

    x3 x2 x1 x0 ... hx
    0 0 0 0 ......... 0
    0 0 0 1 ......... 1
    0 0 1 0 ......... 2
    0 0 1 1 ......... 3
    0 1 0 0 ......... 4
    ...
    Plutôt que d'utiliser l'instruction switch et d'énumérer les 16 cas possibles, j'ai voulu raccourcir en utilisant des structures if ... else.

    Si hexa vaut '0' ou '1' ou '3' ou ...
    x3 prend la valeur 0.
    Sinon x3 prend la valeur 1.


    Même système pour x2. x1 et x0 en adaptant les valeurs de hexa.

    Mais en effet celà ne fonctionne pas

    j'ai vérifié à l'aide de printf que la variable hexa transmise à la fonction hexaBinaire correspondait bien à celle tapée au clavier : c'est bon à ce niveau là.

    Les variables x3, x2, x1 et x0 étant déclarées hors de toutes fonctions, elles devraient être accessible et modifiable aussi bien dans main que dans hexaBianire.

    Je continue à tester et à chercher ce qui ne va pas mais j'ai l'impression de sécher sur ce coup là
    Je vais réecrire la fonction demain en utilisant l'instruction switch ... ça me permettra de savoir si le problème vient de mes if ... else ... ou de la construction de ma fonction.


    PS : dernier else de la fonction hexaBinaire remplacé par :
    Code:
    } else { x0 = 1; }

  10. #9
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Et voilà la fonction hexaBianire réecrite avec l'instruction switch
    Cette fois-ci, c'est sûr ça fonctionne !

    Le code :

    Code:
    void hexaBinaire (char hexa)
    {
    
        switch (hexa)
        {
            case '0' :  x3 = 0; x2 = 0; x1 = 0; x0 = 0;
                        break;
            case '1' :  x3 = 0; x2 = 0; x1 = 0; x0 = 1;
                        break;
            case '2' :  x3 = 0; x2 = 0; x1 = 1; x0 = 0;
                        break;
            case '3' :  x3 = 0; x2 = 0; x1 = 1; x0 = 1;
                        break;
            case '4' :  x3 = 0; x2 = 1; x1 = 0; x0 = 0;
                        break;
            case '5' :  x3 = 0; x2 = 1; x1 = 0; x0 = 1;
                        break;
            case '6' :  x3 = 0; x2 = 1; x1 = 1; x0 = 0;
                        break;
            case '7' :  x3 = 0; x2 = 1; x1 = 1; x0 = 1;
                        break;
            case '8' :  x3 = 1; x2 = 0; x1 = 0; x0 = 0;
                        break;
            case '9' :  x3 = 1; x2 = 0; x1 = 0; x0 = 1;
                        break;
            case 'A' :  x3 = 1; x2 = 0; x1 = 1; x0 = 0;
                        break;
            case 'B' :  x3 = 1; x2 = 0; x1 = 1; x0 = 1;
                        break;
            case 'C' :  x3 = 1; x2 = 1; x1 = 0; x0 = 0;
                        break;
            case 'D' :  x3 = 1; x2 = 1; x1 = 0; x0 = 1;
                        break;
            case 'E' :  x3 = 1; x2 = 1; x1 = 1; x0 = 0;
                        break;
            case 'F' :  x3 = 1; x2 = 1; x1 = 1; x0 = 1;
                        break;
            default : printf("\nValeur incorrecte !");
    
        }
    Pas mal d'optimisation à faire (retour d'un code d'erreur dans la fonction main par exemple), mais je devrais bientôt pouvoir l'intégrer dans un autre programme

    Me reste plus qu'à comprendre pourquoi la structure ... if ... else ... ne fonctionnait pas

    Un grand merci vous et particulièrement à Faith

  11. #10
    invite2d7144a7

    Re : langage C : problème avec variable globale et scanf

    Bonjour,
    Citation Envoyé par gizmo2937 Voir le message
    Me reste plus qu'à comprendre pourquoi la structure ... if ... else ... ne fonctionnait pas
    Sincèrement, comment pouvait-elle fonctionner ?

    Où as-tu vu ce genre de code:
    Code:
        if ( hexa == ('0' + '1' + '2' + '3' + '8' + '9' + 'A' + 'B') )
    Tu n'as pas l'impression d'avoir tout faux en écrivant ça ?
    Faire une suite genre 'A' + 'B' ... ne signifie absolument pas OU au sens logique, tu ne fais qu'additionner les valeurs, et le test sur hexa sera donc toujours faux.

    De plus, ta fonction utilise des variables globales : c'est à proscrire pour programmer proprement.

  12. #11
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Merci whoami.

    Effectivement je peux copier cent fois (au moins) "En langage C l'opérateur logique OU s'écrit || et non pas + "

    Les variables globales me gênent un peu aussi mais je n'ai pas encore trouvé de moyen de les supprimer. Je souhaite que la fonction hexaBinaire soit exportable vers d'autres programmes, et je ne veux donc pas inclure d'autres instructions que la conversion dedans.

    Est-ce que vous avez des pistes à me donner pour que je prenne les bonnes habitudes tout de suite ?

  13. #12
    invite2d7144a7

    Re : langage C : problème avec variable globale et scanf

    Bonjour,

    Il suffit de changer le nombre de paramètres de la fonction, en passant l'adresse des variables destinées à recevoir les résultats.

    À propos, il serait souhaitable de définir une structure réunissant tes 4 variables au lieu d'en utiliser 4 indépendantes (principe : regrouper ce qui va toujours ensemble).

  14. #13
    zoup1

    Re : langage C : problème avec variable globale et scanf

    Citation Envoyé par gizmo2937 Voir le message
    Effectivement je peux copier cent fois (au moins) "En langage C l'opérateur logique OU s'écrit || et non pas + "
    Je ne sais pas si cela peux te faire du bien de copier 100 fois cela, mais il faut quand même que tu sois conscient que même si tu change le + en || la condition if que tu as écrite ne fonctionnera pas.

    En écrivant ta condition if, tu fais des ou logiques entre entre avec des caractères.
    Je te donne une idée, tu me donnes une idée, nous avons chacun deux idées.

  15. #14
    invited5095748

    Re : langage C : problème avec variable globale et scanf

    Effectivement, si tu veux tester si X est égal à A ou B, tu dois écrire :
    Code:
    if ( (X==A) || (X==B) )
    et non
    Code:
    if ( X == ( A||B) )
    En C, je pense que les tests logiques retournent 0 quand c'est faux, et 1 quand c'est vrai. Mais toute autre valeur que 0 est également considérée comme vraie.
    Donc, l'expression
    Code:
    (A||B)
    vaudra 1 si A ou B est différent de 0.

  16. #15
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Ces opérateurs portent d'ailleurs très bien leurs noms d'opérateurs logiques !
    Il faut, pour les utiliser convenablement, que les valeurs de part et d'autre de l'opérateur soit des booléens.

    J'aurai pu utiliser la structure ... if ... else en l'écrivant de cette façon :

    Code:
    if ( (hexa == '0') || (hexa == '1') || ...
    Mais ça aurait donné quelque chose de très lourd et de peu compréhensible. Finalement, je pense que l'instruction switch n'est pas si mal que ça pour réaliser cette fonction A mon niveau bien sûr !
    Je me doute qu'il existe des moyens surement bien plus concis de convertir de l'hexa au binaire.

    Bon maintenant, je m'attaque à l'adressage de variables !
    Merci pour toutes vos remarques

  17. #16
    invited5095748

    Re : langage C : problème avec variable globale et scanf

    Citation Envoyé par gizmo2937 Voir le message
    Ces opérateurs portent d'ailleurs très bien leurs noms d'opérateurs logiques !
    Il faut, pour les utiliser convenablement, que les valeurs de part et d'autre de l'opérateur soit des booléens.
    Je ne sais pas exactement ce que tu entends par là, mais en C, le type booléen n'existe pas. On utilise donc généralement des int, et généralement de valeurs 0 ou 1.
    Mais il est aussi fréquent de faire des tests sur des valeurs tout à fait différentes, et il ne s'agit pas d'un usage incorrect.

    Exemple, avant une division :

    Code:
    if(Y) {
        Z = X/Y; 
    }else{
        printf("Je peux pas diviser par 0...");
    }
    Bonne chance pour la suite (courage pour les pointeurs )

  18. #17
    invitedba13d1f

    Re : langage C : problème avec variable globale et scanf

    Merci pour ces précisions Lignux

    On utilise pas le terme booléen mais le fonctionnement est le même (à priori) ! On est toujours limité à deux "valeurs" possible : '0' ou 'toute autre valeur'.
    Utiliser les opérateurs logiques comme je l'ai fait avec des valeurs constantes ... sans commentaire

    J'avais déjà travaillé sur les pointeurs pour travailler avec des fichiers, donc ça n'a posé trop de problème
    Ca marche du premier coup pour une fois

    Voici le code sans variables globales :

     Cliquez pour afficher


    Il me reste encore à créer une gestion d'erreur un peu plus poussée (c'est léger un printf pour gérer l'erreur !).
    Le but de la fonction hexaBinaire est d'être intégrée à un programme décodant un fichier entier !!

    Je pense faire comme ça :
    A chaque fois qu'un caractère lu dans le fichier à convertir ne sera pas une valeur hexa on l'ignorera (saut au caractère suivant).
    Si il ne s'agissait pas d'un caractère de fin de ligne (\n) ou de fin de fichier (EOF) on incrémentera une variable créee pour l'occasion.
    Celà permettra de savoir à la fin de la conversion si des problèmes on été rencontrés.

    Donc encore pas mal de pain sur la planche

  19. #18
    invite2d7144a7

    Re : langage C : problème avec variable globale et scanf

    Bonjour,

    Autre précision : dans un programme C, on ne définit pas les fonctions dans une fonction
    Code:
    int main()
    {
        void hexaBinaire (char hexa, int *x3, int *x2, int *x1, int *x0);
    ...
    (eh oui, main est une fonction comme une autre).

    Certains compilateurs acceptent ta manière de faire, mais ce n'est pas standard.

    Il faut faire
    Code:
        void hexaBinaire (char hexa, int *x3, int *x2, int *x1, int *x0);
    
    int main()
    {...
    D'autre part, comme je l'ai déjà dit, il faudrait définir une structure pour regrouper tes variables, qui de toute manière sont destinées à être utilisées ensemble.

    Et mieux encore, utiliser un tableau de 4 valeurs, ce qui permettra de travailler avec une boucle, simplifiant le code.

    Et toujours mieux :

    Pourquoi tiens-tu à décomposer le résultat en 4 valeurs, une seule serait suffisante pour renvoyer le résultat binaire.

  20. #19
    polo974

    Re : langage C : problème avec variable globale et scanf

    Question en passant: à quoi sert ce bout de code????
    Code:
        int c=0;
        while ( (c = getchar() != '\n') && (c = getchar() != EOF) )
        {
            ;
        }
    C'est le scanf qui donne la valeur à transcoder...

    Ensuite, au choix, on néglige les caractères hors plage attendue ou non.
    Code:
    if((hexa >= '0' && (hexa <= '9'))
        hexa -= '0';
    else if ((hexa >= 'A' && (hexa <= 'F')) 
        hexa-= 'A-10';
    else if ((hexa >= 'a' && (hexa <= 'f'))  /* si on veut les minuscules */
        hexa-= 'a-10';
     
    x0= hexa & 1? 1: 0;
    x1= hexa & 2? 1: 0;
    x2= hexa & 4? 1: 0;
    x3= hexa & 8? 1: 0;
     
    /*
    écriture équivalente à des
    if(hexa &1)
       x1=1;
    else
       x1=0;
    etc...
    mais tellement plus lisible...
    */

Discussions similaires

  1. PIC18F interuption et variable globale
    Par invite2f4dfe22 dans le forum Électronique
    Réponses: 7
    Dernier message: 07/08/2012, 16h04
  2. matlab variable globale
    Par invitea255964f dans le forum Logiciel - Software - Open Source
    Réponses: 2
    Dernier message: 04/06/2009, 08h37
  3. langage C : problème avec scanf
    Par invitedba13d1f dans le forum Logiciel - Software - Open Source
    Réponses: 20
    Dernier message: 20/04/2009, 18h41
  4. problème avec le langage pascal
    Par invite49b54ac2 dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 28/01/2009, 12h45
  5. problème avec langage C++
    Par invite0f6e0be6 dans le forum Logiciel - Software - Open Source
    Réponses: 5
    Dernier message: 03/10/2007, 12h20
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...