Fedit ( editeur hexadecimal en mode texte)

Contenu du snippet

Un éditeur hexa très simple avec rien que du printf pour l'affichage (sous xp avec un pc récent on y voit que du feu :) ).
Il met en oeuvre principalement des accès aux fichiers

Du coté des fonctions on a, une recherche de chaine hexadecimal/ascii, une fonction de modification des données et une fonction d'annulation. Le tout présenté par un bon vieux menu à choix

Il est compilé avec c++ builder 4 mais comme il n'y a que des fonctions basiques, n'importe quel compilateur devrait faire l'affaire !

Passont aux défauts (bin oui y en a aussi)
La capture de la réponse se fait par l'intermédiaire d'un kbhit qui bouffe tout le temps cpu
La fonction de recherche bugge sous xp (pas de problème sur 95/98)
Il n'est possible de modifier qu'un seul octet à la fois
La modification se fait directement sur le fichier
Je l'ai écrit comme un bourrin quand j'étais en bts...

Source / Exemple :


/************************/
                         /*  editeur de fichier  */
                         /************************/

#include <stdio.h>
#include <errno.h>
#include <mem.h>
#include <dos.h>   
#include <io.h>
#include <conio.h>    
#include <string.h>

/*************************/
/* fonction de recherche */
/*************************/

unsigned long int chercher(char *chaine,int lu ,FILE *fichier)
{
 unsigned long int poschaine=0;
 int crschaine;
 char occurence=0, car[16], temp;

 while ((feof(fichier)==0)&&(occurence==0))
 {
  fread(&temp,1,1,fichier);
  if (temp==chaine[0])
  {
   fseek(fichier,-1,SEEK_CUR);
   fread(car,1,lu,fichier);                  
   if (strncmp(car,chaine,lu)==0)       
   {
    poschaine=ftell(fichier)-lu;
    occurence=1;
   }
   else fseek(fichier,(-lu+1),SEEK_CUR);
  }
 }

 if (occurence==0)
 {
  printf("\nAucune occurence trouvee\n");
  sleep(1);
 }

 return poschaine;
}

/************************/
/* fonction d'affichage */
/************************/

void affiche(long offset, FILE *fichier)
{
 int donneesligne[16];
 int crsligne, nbligne, bourrage;

 printf("\n\t\t\t     Editeur de fichier\n");

 fseek(fichier, offset,SEEK_SET);   
 printf(" offset     00 01 02 03 04 05 06 07   08 09 0A 0B 0C 0D 0E 0F\n");
 printf("--------------------------------------------------------------------------------");

 /**************************/
 /* affichage des 16 lignes*/
 /**************************/

 for (nbligne=0;((nbligne<16)&&(feof(fichier)==0));nbligne++)
 {
  memset(donneesligne,0,sizeof(donneesligne));         

  /******************/
  /* lect du fichier*/
  /******************/

  for(crsligne=0;(crsligne<16);crsligne++)
   donneesligne[crsligne]=fgetc(fichier);

  printf(" %08x : ",offset+nbligne*16); 

  /******************************/
  /* aff des 16 colonnes en hexa*/
  /******************************/

  for (crsligne=0;((crsligne<16)&&(donneesligne[crsligne]!=-1));crsligne++)
  {
   if (crsligne==8) printf("- ");
   printf("%02x ",donneesligne[crsligne]);
  }
  printf(" ");

  if (crsligne<16)     
  {
   bourrage=(3*(15-crsligne))+2;
   if (bourrage >23) bourrage+=2;  
   for (crsligne=0;crsligne<=bourrage;crsligne++) printf(" ");
  }

  
  for (crsligne=0;((crsligne<16)&&(donneesligne[crsligne]!=-1));crsligne++)
  {
   /*caractere special (LF/CR, tab ...)*/
   if 

((donneesligne[crsligne]==0)||(donneesligne[crsligne]==7)||(donneesligne[crsligne]==9)||(donneesligne[crsligne]==10)

||(donneesligne[crsligne]==13))
    printf(".");   
   else printf("%c",donneesligne[crsligne]);   
  }
  printf("\n");
    
 }

 if (nbligne<15)      
 {
  bourrage=15-nbligne;
  for (crsligne=0;crsligne<=bourrage;crsligne++) printf("\n");
 }

}

/*******************************/
/* main, gestion des commandes */
/*******************************/

void main(int argc, char *argv[])
{
 FILE *fichier;
 char reponse=0, oldreponse, sousreponse;
 char donnee, oldonnee;
 char chaine[16], temp[32];
 unsigned long int offset=0, oldoffset, taillefichier, tempset;
 int crschaine, lu;

 /*********************/
 /* ouverture fichier */
 /*********************/
 
 if (argc!=2) printf("il faut le nom du fichier a editer\n");
 else
 {
  fichier=fopen(argv[1],"r+b");

  if ((fichier==(FILE* )-1)||(fichier==(FILE* )0)) 
   printf("impossible d'ouvrir le fichier, verifiez que le nom du fichier et le chemin sont corrects\n");

  else   
  {
   fseek(fichier,0,SEEK_END);
   taillefichier=ftell(fichier);
   rewind(fichier);

   /*affichage de la 1ere page*/
   affiche(offset,fichier);

   do
   {

    /********************************************/
    /* affichage d'infos du fichier & commandes */
    /********************************************/

    printf("--------------------------------------------------------------------------------");
    printf("  fichier : %s - %d octets\n",argv[1],taillefichier);
    printf("\t\t\t\t\t deplacement : %d",offset);
    printf("  hexa : %x\n",offset);
    printf("--------------------------------------------------------------------------------");
    printf("0-quitter 1-pgup 2-pgdn 3-pos offset 4-chg val 5-rech chaine 6-occ suivante\n7-annuler :");

    while (kbhit()==0);

    reponse=(char)getch();

    
    fflush(stdin);

    /********************************/
    /* interpretation des commandes */
    /********************************/

    switch (reponse-48)
    {
     /*sortie de l'editeur*/
     case 0 : {
               printf("fermeture du fichier %s",argv[1]);               
               fclose(fichier);
              }
            break;

     /*page precedente*/
     case 1 : {
               oldoffset=offset;

               if (offset>=0x100)
                {offset-=0x100;
                 affiche(offset,fichier);
                }
               else {offset=0; affiche(offset,fichier);}

               oldreponse=1;
              }
            break;

     /*page suivante*/
     case 2 : {
               oldoffset=offset;

               if  (offset+0x100>taillefichier)
                offset=(taillefichier-0xf0)-(taillefichier-0xf0)%16;
               else offset+=0x100;
               affiche(offset,fichier);

               oldreponse=2;
              }
            break;

     /*page depuis un offset donne*/
     case 3 : {
               oldoffset=offset; 

               
               printf("\nEntrez la nouvelle position en hexa max=%x : ",taillefichier);
               scanf("%x",&offset);
               fflush(stdin);

               
               offset=offset-(offset%16);
               if (offset>taillefichier)
                offset=taillefichier-(taillefichier%16);
               affiche(offset,fichier);

               oldreponse=3;
              }
            break;

     /*modification d'un octet a l'offset indique*/
     case 4 : {
               
               printf("Entrez l'offset en hexa de la valeur a changer : ");
               scanf("%x",&offset);
               fflush(stdin);

               
               fseek(fichier,offset,SEEK_SET); 
               oldonnee=fgetc(fichier);

               
               printf("la valeur %x en %x sera remplacee par : ",oldonnee,offset);
               scanf("%x",&donnee);
               fflush(stdin);

               
               fseek(fichier,offset,SEEK_SET);
               fwrite(&donnee,1,1,fichier);

               affiche(offset-(offset%16),fichier);

               oldreponse=4;

              }
            break;

     /*recherche d'une chaine*/
     case 5 : {

               oldoffset=offset;

               /*positionnement au debut du fichier*/
               rewind(fichier);

               
               printf("recherche 1-hexa 2-ascii : ");
               scanf("%x",&sousreponse);

               /*saisie de la chaine a chercher*/
               memset(chaine,0,sizeof(chaine));         

               printf("entrez la chaine a rechercher (16 car max): ");

               if (sousreponse==1) 
               {
                memset(temp,0,sizeof(temp));           

                lu=(read(0,temp,32)-1)/2;

                for (crschaine=0;crschaine<lu;crschaine++)
                {
                 if (temp[crschaine*2]>58)
                  chaine[crschaine]=16*(temp[crschaine*2]-87);
                 else chaine[crschaine]=16*(temp[crschaine*2]-48);

                 if (temp[(crschaine*2)+1]>58)
                  chaine[crschaine]+=(temp[(crschaine*2)+1]-87);
                 else chaine[crschaine]+=(temp[(crschaine*2)+1]-48);

                }
               }
               else  lu=read(0,chaine,16)-1;         

               offset=chercher(chaine,lu,fichier);

               tempset=offset;
               
               affiche(offset-(offset%16),fichier);

               oldreponse=5;
              }
            break;

     /*recherche occurence suivante*/
     case 6 : {

               
               offset=tempset+0x10;
               fseek(fichier,offset,SEEK_SET);

               oldoffset=offset; 

               offset=chercher(chaine,lu,fichier);

               
               tempset=offset;
               
               affiche(offset-(offset%16),fichier);

               oldreponse=6;
              }
            break;

     /*annulation de la deniere commande*/
     case 7 : {

               if ((oldreponse<=3)||(oldreponse>4))
               {
                if (oldreponse==7) 
                {
                printf("\nUn seul annuler est possible\n");
                sleep(1);
                affiche(offset-(offset%16),fichier);
                }
		/*annuler un deplacement*/
                else 
                {
                 offset=oldoffset;
                 affiche(offset-(offset%16),fichier);
                }
               }
	       /*annuler une modif*/
               else 
               {
                fseek(fichier,oldoffset,SEEK_SET);
                fwrite(&oldonnee,1,1,fichier);
               }
               oldreponse=7;
              }
            break;

     default : {
                printf("\n entrez une reponse entre 0 et 7");
                sleep(1);
                affiche(offset,fichier);
               }
    }
   }while (reponse!=48);
  }
 }
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.