Répondre à la discussion
Affichage des résultats 1 à 14 sur 14

langage C : conversion en binaire d'un fichier en hexa



  1. #1
    gizmo2937

    langage C : conversion en binaire d'un fichier en hexa


    ------

    Bonjour,

    Pour ceux qui ont suivi mon précédent post.

    J'ai intégré ma fonction de conversion hexadécimale vers binaire dans un programme qui décode un fichier complet !

    Voici le code :
     Cliquez pour afficher


    Ce programme converti donc des caractères hexadécimaux contenu dans un fichier "Hexa.hex" en valeur binaire sur 4 bits.
    Le résultat de la conversion est écrit dans un fichier "Conversion.txt" crée par le programme pour l'occasion.
    On ignore tous les caractères non codés en hexa.

    J'aimerai avoir vos avis sur des erreurs éventuelles que contient ce code et sur les modifications que vous y apporteriez.
    C'est déjà moins buggué que mon premier essai

    Merci de votre aide

    -----

  2. Publicité
  3. #2
    lou_ibmix_xi

    Re : langage C : conversion en binaire d'un fichier en hexa

    Salut,

    Puisque tu offres le flanc à la critique, critiquons...

    1°) Utiliser 'goto' c'est mal, alors c'est parfois nécessaire, mais éviter lorsque ça ne l'est pas, surtout lorsque la version sans goto est nettement plus lisible et plus courte, donc pour ta boucle, préfère quelque chose comme:
    Code:
    do {
       caractereLu = fgetc(fichierLu);
       /* On vérifie que le caractère lu soit bien en valeur hexadécimale */
       if (((caractereLu >= 'A') && (caractereLu <= 'Z'))
                      || ((caractereLu >= '0') && (caractereLu <= '9'))) {
           hexa[0] = caractereLu;
           hexaBinaire(&hexa[0], &b[3], &b[2], &b[1], &b[0]);
           fprintf(fichierConverti,"%d%d%d%d",b[3],b[2],b[1],b[0]);
       }
    } while (caractereLu != EOF);
    2°) Tu fais 2 fois le boulot de vérification pour la valeur du caractère que tu passes à ta fonction de conversion, il est nettement mieux de le faire uniquement dans la fonction de conversion, de plus pourquoi passer une chaîne de caractère pour le premier argument lorsque seul 1 caractère suffit? Je te propose donc:
    Code:
    /* fonction convertissant un caractère héxadécimal en binaire sur 4 bits. Retourne -1 si le
     * caractère à convertir n'est pas valide, 0 sinon. */
    int hexaBinaire (char hexa, int *x3, int *x2, int *x1, int *x0) {
        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 : return -1;
        }
       return 10;
    }
    J'ai enlever l'affichage de l'erreur dans la fonction, c'est à l'utilisateur de la fonction de tester la valeur de retour, et de faire le nécessaire en cas d'erreur...

    3°) Il y a une erreur, lorsque tu déclares "int b[3];" "b" est un tableau de trois "int", donc "b[3]" tombe en dehors de ton tableau puisque "3" est le 4ème indice losque le premier est 0...

    Voilà de quoi t'amuser...
    A plus.

  4. #3
    lou_ibmix_xi

    Re : langage C : conversion en binaire d'un fichier en hexa

    Au fait, le cas des minuscules n'est pas traité...

  5. #4
    Goldfish

    Re : langage C : conversion en binaire d'un fichier en hexa

    Salut !

    Une chose très spéciale dans ton programme initial à revoir pour des boucles futurs, tu fais un while(!EOF) et ensuite a l'interieur de ce while tu fais un test if(!EOF) ?!

    Sinon, pour l'instant, je n'ai pas grand chose à ajouter à ce qu'a dit lou_ibmix_xi.

    @+

    PS : Je suis presque certain que tu écris cette fonction dans un but pédagogique (et tu as raison), mais si ce n'étais pas le cas, il me semble que tu peux faire tout ça avec des printf/fprintf/scanf/fscanf (%x).
    }><(({*>

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

    Re : langage C : conversion en binaire d'un fichier en hexa

    Salut,

    Merci pour tes critiques lou_ibmix_xi ! Les critiques constructives c'est ce qui permet d'avancer

    Fini les Goto donc ! Pourquoi n'est il pas conseillé de les utiliser ?
    C'est vrai que dans ce cas là, c'était inutile

    J'ai supprimé la vérification du caractère dans la fonction principale comme tu me l'as conseillé. En fait je ne savais pas comment récupérer le résultat du return avant ce soir
    Voici ce que ça donne :

     Cliquez pour afficher


    Les caractères qui ne sont pas en valeur hexadécimale sont remplacés par 'xxxx' dans le fichier converti. Je rajouterai peut-être une variable qui sera incrémenté à chaque fois que cela arrive.
    Ça permettrai d'être prévenu à la fin de l'exécution du programme.

    Je ne sais pas si il est important de s'occuper des minuscules. Sinon je pourrai faire une autre fonction basée sur un switch pour transformer une minuscule en majuscule.
    Je ne connais pas encore d'instruction qui permette en C de réaliser cela.

    Oui Goldfish, je fais ça pour apprendre. On m'a déconseillé l'usage du scanf en général. Je le remplace donc par fgetc (ou fgets quand je veux lire une chaîne). Chez moi faire un printf("%x",char) ne me donne pas le résultat attendu

    Je revérifie que le caractère lu ne soit pas EOF sinon je me retrouve avec un caractère parasite en fin de fichier (la condition n'est vérifiée qu'en fin de boucle). Pareil pour la vérification sur '\n'. Je suppose que le EOF se place sur la ligne vide et non pas juste derrière le dernier caractère du fichier.

    Merci à tous les deux

  8. #6
    Goldfish

    Re : langage C : conversion en binaire d'un fichier en hexa

    Yop !

    Citation Envoyé par gizmo2937 Voir le message
    Oui Goldfish, je fais ça pour apprendre. On m'a déconseillé l'usage du scanf en général. Je le remplace donc par fgetc (ou fgets quand je veux lire une chaîne). Chez moi faire un printf("%x",char) ne me donne pas le résultat attendu
    Les scanf sont pratiques (et adaptés) je trouve pour récuperer des valeurs numériques ! C'est pour les chaines de caractères qu'ils faut éviter. Essaie plutot avec des codes de ce genre :
    Code:
    int main(){
      int i = 3327338;
    
      printf("%x\n",i);
      
      return 0;
    }
    Tu verras que ça marche bien (j'espere) ! Les hexadecimaux sont des chiffres.

    Pour faire la conversion tu peut faire par exemple le scanf en %x et le printf en %d je pense ça marche, il faut tester...

    @+
    }><(({*>

  9. Publicité
  10. #7
    gizmo2937

    Re : langage C : conversion en binaire d'un fichier en hexa

    Mmmh ok !

    C'est utile pour faire la conversion décimale / hexadécimale !

    Moi pour l'instant je souhaite réaliser une conversion hexadécimale / binaire. Je ne pense pas qu'on puisse le faire directement avec un printf ... ou alors mon programme va devenir beaucoup plus simple

  11. #8
    lou_ibmix_xi

    Re : langage C : conversion en binaire d'un fichier en hexa

    Fini les Goto donc ! Pourquoi n'est il pas conseillé de les utiliser ?
    C'est surtout pour la facilité à comprendre le flux d'un programme, avec du goto, tu as très vite transformer ton code en sac de nouilles.
    A l'inverse, les "if" et autre "while" se lisent de haut en bas et de dehors à dedans.
    L'utilisation du goto est très bien pour un même point de sortie pour plusieurs conditions d'erreurs d'une fonction, pour faire le ménage.

    Je ne sais pas si il est important de s'occuper des minuscules. Sinon je pourrai faire une autre fonction basée sur un switch pour transformer une minuscule en majuscule.
    C'est surtout que c'est simple, ca coûte 6 lignes à ta fonction, et ce sont 6 "case"...

    faire un printf("%x",char) ne me donne pas le résultat attendu
    Si tu écrits textuellement ça c'est normal, c'est printf ("%c", _c_), si _c_ est un char. Si tu est sous linux, bsd ou autres unix, "man 3 printf" t'explique tout.

    Rapidement, après avoir lu ton nouveau code, remarques:
    -as quoi sert la variable hex?
    -as quoi sert la variable test, pourquoi ne pas mettre la fonction directement en condition du if,
    -si il y a une plusieurs conditions liées par des ops logiques, elles sont faites de gauche à droite et s'arrêtent dès que possible (le résultat est vrai ou faux), tu peux alors économiser l'appel de ta conversion si le caractere est 'EOF' ou '\n'.
    Dernière modification par lou_ibmix_xi ; 29/06/2009 à 20h51. Motif: validation prématurée

  12. #9
    Goldfish

    Re : langage C : conversion en binaire d'un fichier en hexa

    Citation Envoyé par gizmo2937 Voir le message
    Mmmh ok !

    C'est utile pour faire la conversion décimale / hexadécimale !

    Moi pour l'instant je souhaite réaliser une conversion hexadécimale / binaire. Je ne pense pas qu'on puisse le faire directement avec un printf ... ou alors mon programme va devenir beaucoup plus simple
    Effectivement, le printf ne gere pas le binaire... Mais en récuperant les nombres comme ça, tu ne t'embete plus avec l'hexadecimal, c'est déjà bien

    Si tu veux du vrai binaire, tu peux écrire dans un fichier texte en binaire (avec l'option "wb" au lieu de "wt" et des fonctions un peu plus chiante que fprintf). Mais je ne pense pas que ce soit ce que tu cherche et, une fonction qui passe du décimal au binaire doit prendre 5 lignes max je pense.

    Surtout ne t'arrête pas !! Finis ta fonction

    @+
    }><(({*>

  13. #10
    gizmo2937

    Re : langage C : conversion en binaire d'un fichier en hexa

    Voici mon nouveau code après avoir tenu compte de tes remarques lou_ibmix_xi !

     Cliquez pour afficher


    Donc si on prend point par point :

    1) La variable hexa
    Je l'ai supprimé En effet elle ne servait à rien puisqu'on pouvait utiliser la variable caractereLu directement.

    2) La variable test
    Je l'ai supprimé aussi ! Là par contre j'ai hésité un peu. On utilise une variable de moins mais on fait un appel de plus à la fonction de conversion. Je ne suis pas certain que se soit gagnant. Qu'est ce que vous en pensez ?

    3) L'ordre des conditions dans mes boucles
    J'ai modifié là aussi pour que l'appel à la fonction de conversion ne se fasse que si les conditions précédentes sont vérifiées.

    4) Le cas des minuscules
    J'ai fait un simple décalage du code ASCII. Est-ce que ça pose des problèmes au niveau de la portabilité du programme ?


    Sinon, je n'ai pas accès au "man 3 printf"
    Il me dit No manual entry for printf in section 3.
    Pourtant à la fin de man printf il est écrit : See also printf(3)

    J'ai été consulté la doc sur Internet mais vous savez pourquoi ça ne fonctionne pas sous la console ?

    Surtout ne t'arrête pas !! Finis ta fonction
    Ne t'inquiètes pas, je n'ai pas l'intention d'abandonner

    Merci encore à tous les deux pour vos conseils
    Dernière modification par gizmo2937 ; 30/06/2009 à 18h23. Motif: précisions !

  14. #11
    Goldfish

    Re : langage C : conversion en binaire d'un fichier en hexa

    Salut !!

    Je n'ai pas lu tout ton code, juste un petit conseil qui ne coûte rien et qui est très courant...

    Lorsque tu ouvre un fichier tu peux faire le test du succès directement ce qui te permet de rendre ton code plus clair après (une indentation en moins)

    Code:
    if((monfichier = fopen("truc.txt","rt")) == NULL)
      exit(0);
    Ainsi, tu ouvre le fichier, tu test l'ouverture et tu quitte le programme en cas d'echec.

    Je te conseil aussi de toujours préciser dans quel mode tu ouvre ton fichier, tu ne met que "r" (donc lecture) il vaut mieux mettre "rt" (donc lecture en mode texte) ! C'est rare mais tu peux avoir des problèmes de portabilité, certains sytèmes ouvre le fichier par default en binaire et pas en texte !!

    @+
    }><(({*>

  15. #12
    lou_ibmix_xi

    Re : langage C : conversion en binaire d'un fichier en hexa

    2) La variable test Je l'ai supprimé aussi ! Là par contre j'ai hésité un peu. On utilise une variable de moins mais on fait un appel de plus à la fonction de conversion. Je ne suis pas certain que se soit gagnant. Qu'est ce que vous en pensez ?
    Tu as tout à fait raison, mais faire le test de caractereLu == '\n' ou EOF ne te servirai que si tu voulais traiter cette erreur différement d'une erreur de ta fonctin de conversion, qui englobe ce test... Donc le plus simple pour le même resultat c'est:
    Code:
    if (hexaBinaire(&caractereLu, &b[3], &b[2], &b[1], &b[0]) == 0) {
       printf (fichier, "%d%d%d%d", b[3], b[2], b[1], b[0]);
    } else {
       printf (fichier, "xxxx");
    }
    4) Le cas des minuscules
    J'ai fait un simple décalage du code ASCII. Est-ce que ça pose des problèmes au niveau de la portabilité du programme ?
    C'est surtout que ce n'est pas logique de le faire en amont, je te redonne mon indice, c'est des "case" (et uniquement des "case") à ajouter dans ta fonction de conversion, un petit indice supplémentaire, que ce passe-t'il si il n'y a pas de "break" après un "case"? Mais parler de portabilité c'est très bien!

    Sinon, je n'ai pas accès au "man 3 printf"
    il doit te manquer la documentation de la bibliothèque standard, sous FEDORA le paquetage doit être "glibc-devel", sous les autres linux je ne sais pas mais cherche "glibc" dans ton gestionnaire de paquetage et je pense que tu devrais trouver.

    D'autres trucs qui me chipotent:
    -si il n'y a pas de "else" complétant un "if", n'en mets pas... ça surcharge pour rien.
    -evite les constantes numériques, "if ( (caractereLu >= 97) && (caractereLu <= 102) )" c'est mal, on ne comprends pas, "if ( (caractereLu >= 'a') && (caractereLu <= 'f') )" c'est mieux et ça ne coûte pas plus cher...
    -pourquoi passes-tu un pointeur sur le caractère lu à ta fonction de conversion?

    D'autres remarques:
    -la présentation du code source c'est très, très, très, très, très important, ce n'est pas un caprice de profs (qui d'ailleur n'insistent pas assez là-dessus je trouve). En effet, du code bien écrit c'est du code qui est plus facile à lire, donc à comprendre, et donc on à moins de chance d'introduire des erreurs, et/ou on trouvera les erreurs plus rapidement. Je te dis ça car il faut que celà devienne un reflexe pour ne plus y penser, donc autant prendre le plis dès le départ...
    -Je ne veux absolument pas te décourager, mais je voudrais savoir ce qui t'interessent dans la programmation et ton niveau, car le C ce n'est pas forcement le mieux pour commencer, et suivant les domaines de l'informatique qui t'interressent, ce n'est pas l'outils que tu utiliseras.
    -Si une 40aine d'euros sont à ta porté (et que tu décides de continuer sur le C), il faut que tu achète la bible: "Le Langage C", la 2nde édition (parfois appelée "norme ANSI"), de Kernighan et Ritchie, c'est la référence absolument (ce sont les inventeurs du C, déifiés par la plupart des informaticiens, dont moi) et c'est très bien pour débuter.

    Bonne continuation et à bientôt

  16. Publicité
  17. #13
    gizmo2937

    Re : langage C : conversion en binaire d'un fichier en hexa

    Tu as tout à fait raison, mais faire le test de caractereLu == '\n' ou EOF ne te servirai que si tu voulais traiter cette erreur différement d'une erreur de ta fonctin de conversion, qui englobe ce test... Donc le plus simple pour le même resultat c'est:
    Code:
    if (hexaBinaire(&caractereLu, &b[3], &b[2], &b[1], &b[0]) == 0) {
       printf (fichier, "%d%d%d%d", b[3], b[2], b[1], b[0]);
    } else {
       printf (fichier, "xxxx");
    }
    Le problème en ne traitant pas les cas des valeurs EOF et '\n', c'est que je vais me retrouver avec des caractères parasites dans mon fichier converti. J'aurai, au minimum 8x à la fin de mon fichier correspondant au saut de ligne suivi de la fin de fichier.


    J'ai intégré le cas des minuscules à ma fonction de conversion. Voilà ce que ça donne :

     Cliquez pour afficher


    Pour le "man 3 printf", sous Ubuntu le paquet nécessaire s'appelle tout simplement "manpages"

    Pour le pointeur utilisé dans ma conversion :
    Je l'ai enlevé. Il aurait en effet été utile uniquement si je souhaitais modifier ma variable caractereLu dans ma fonction de conversion.
    C'est enregistré, pas de retour de la variable = pas de nécessité d'utiliser un pointeur

    Mes motivations pour apprendre le C :
    C'est parti au départ d'un projet de création de base de donnée !
    On souhaitait avec deux collègues réaliser une base de donnée SAV correspondant vraiment à nos besoins ... on c'est vite rendu compte qu'il été nécessaire de maitriser un langage de programmation pour faire cela et le C à l'air plutôt adapté à cette usage.
    Ça faisait longtemps aussi que je souhaitais apprendre un langage de programmation. J'ai codé un peu (vraiment peu ) au lycée en assembleur, en ABEL et en VHDL et ça me plaisait beaucoup.
    Je souhaite reprendre mes études à la rentrée (en attente des résultats aux tests d'admission) cela me donne une envie supplémentaire pour apprendre un langage de programmation (autant prendre un peu d'avance, le C est au programme ).

    Voilà pour le côté personnel de la chose

  18. #14
    lou_ibmix_xi

    Re : langage C : conversion en binaire d'un fichier en hexa

    Salut,

    Trève de suspens, je te montre la solution à laquelle je pensais pour traiter le cas des minuscules:
    Code:
    switch (caractereLu) {
    
        case '0':
        *x3 = 0; *x2 = 0; *x1 = 0; *x0 = 0;
        break;
    
        /* ... Les autres cas jusqu'a '9' ... */
    
        case 'a':
        case 'A':
        *x3 = 1; *x2 = 0; *x1 = 1; *x0 = 0;
        break;
    
        case 'b':
        case 'B':
        *x3 = 1; *x2 = 0; *x1 = 1; *x0 = 1;
        break;
    
        /* etc ... */
    }
    C'est parti au départ d'un projet de création de base de donnée !
    On souhaitait avec deux collègues réaliser une base de donnée SAV correspondant vraiment à nos besoins
    Des bases de données il en existent des gratuites, MySQL ou autre, je ne suis pas un spécialiste mais google t'en dira certainement plus. Ces bases de données sont à mon avis suffisament générique pour pouvoir répondre à la plupart des besoins...
    De plus, écrire une base de donnée en C, c'est vraiment un boulot énorme, et pour une équipe de programeurs expérimentés...
    Le C reste LE langage pour faire de la programmation bas-niveau, c'est à dire programmer des pilotes de périphériques et le noyau de l'OS, des systèmes embarqués comme ton lecteur MP3 ou le calculateur de ta voiture... Bref la plupart du temps le C c'est pour l'informatique "invisible".
    Pour tout le reste, il faut plutôt utiliser des langages de plus haut-niveau comme le C++, java, PERL et autres python... Et je pense que, mis à part le C++, ces 3 langages sont également mieux adaptés pour une première découverte de l'informatique où il faut que tu comprennes comment concevoir un algo, structurer tes données et faire marcher le tout ensemble...

Discussions similaires

  1. conversion Hexa-BCD en assembleur
    Par stgi02 dans le forum Électronique
    Réponses: 19
    Dernier message: 24/06/2009, 12h58
  2. conversion hexa -->image
    Par kayser33 dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 20/03/2008, 08h49
  3. conversion binaire en 7 segments d'un clavier matriciel
    Par Laurent.P dans le forum Électronique
    Réponses: 3
    Dernier message: 10/03/2008, 12h21
  4. Conversion hexa-binaire dans une macro Excel
    Par jecario dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 06/06/2007, 21h47
  5. Creation d'un fichier excel langage C
    Par Nithael dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 26/03/2007, 22h23
Découvrez nos comparatifs produits sur l'informatique et les technologies.