Supprimer une chaine de caracteres d'un fichier

0/5 (10 avis)

Snippet vu 23 551 fois - Téléchargée 32 fois

Contenu du snippet

En réponse à de nombreuses questions, voici un code qui supprime une ligne dans un fichier.
Ce code crée un fichier temporaire et le supprime en sortie du programme.

#include <stdio.h>
#include <windows.h>


// Taille du buffer de lecture
#define ONEMEGA     0x100000

//Permet de supprimer la chaine String du fichier FileName
DWORD deleteStringInFile(char *FileName, char *String); 

int main(int argc,char ** argv) 
{ 
 // Test des paramètres 
 if (argc!=3) 
 { 
   printf("Problem when calling the applicationn"); 
   printf("Exemble: exe test.txt coucou2n"); 
   system("pause"); 
   return -1; 
 } 
 
  // Appel à la fonction 
  DWORD result=deleteStringInFile(argv[1],argv[2]); 
  printf("%sn", (result==0) ? "pas trouvé" : "trouvé");
  system("pause");

  return 0; 
} 



DWORD deleteStringInFile(char *FileName, char *String) 
{ 
  char *buffer;     // Buffer de lecture
  char *c, *pout;   // Délimiteurs
  unsigned int i,lenfind=strlen(String); 
  DWORD dwread,dwritten,bfound=0;

  // Ouverture d'un fichier temporaire
  HANDLE htemp = CreateFile("temp.txt",GENERIC_WRITE,0,0,CREATE_NEW,FILE_FLAG_SEQUENTIAL_SCAN,0);
  if (htemp==INVALID_HANDLE_VALUE)
    return 0;

  // Ouverture du fichier en mode lecture 
  HANDLE hfile = CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
  if(hfile==INVALID_HANDLE_VALUE)
    return 0;

  // Allocation du buffer dans le tas
  // sinon, stack overflow surement
  buffer=(char *)HeapAlloc(GetProcessHeap(), 0, ONEMEGA);

fromFL:
  // Remplissage du buffer
  dwread=0;
  ReadFile(hfile,buffer,ONEMEGA,&dwread,0);

  if (bfound)
  {
    // Si la chaine a été trouvée, on se contente d'écrire
    // et on quitte si on a lu moins d'un Mo
    WriteFile(htemp,buffer,dwread,&dwritten,0);
    if (dwread!=ONEMEGA)
      goto closeFL;
    else
      goto fromFL;
  }

  // Si le nombre de caractères lus < taille de String alors exit
  if(dwread<lenfind)
    goto closeFL;

  // Init des délimiteurs
  pout=buffer+dwread-lenfind;
  c=buffer;

firstcar: // test du 1er caractère
  while(*c!=String[0])
  {
    // Test s'il reste assez de caractères
    if(++c>=pout)
    {
      if(dwread!=ONEMEGA)
        goto closeFL;
      WriteFile(htemp,buffer,dwread,&dwritten,0);
      goto fromFL;
    }
  }
  for(i=1; i<lenfind; i++)
  {
    if(c[i]!=String[i])
      goto notfound;
  }

  // OK! Chaine trouvée!
  bfound=1;
  WriteFile(htemp,buffer,c-buffer,&dwritten,0);
  WriteFile(htemp,c+lenfind,pout-c,&dwritten,0);
  goto fromFL;

notfound:
  // KO, pas trouvée :(
  // s'il reste assez de caractères, on continue avec le même buffer
  if(++c<pout)
    goto firstcar;

  if(dwread==ONEMEGA)
  {
    // sinon, lecture d'un nouveau buffer
    WriteFile(htemp,buffer,dwread,&dwritten,0);
    goto fromFL;
  }

closeFL:
  // Fermeture des fichiers
  CloseHandle(hfile);
  CloseHandle(htemp);

  // Si la chaine a été trouvée, on ré-écrit le fichier
  if (bfound)
    CopyFile("temp.txt",FileName,false);

  // Destruction du fichier temporaire
  DeleteFile("temp.txt");

  // Désallocation du buffer
  HeapFree(GetProcessHeap(),0,buffer);
  
  // Fin
  return bfound;
}

A voir également

Ajouter un commentaire Commentaires
waynes6938 Messages postés 1 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 avril 2007
30 avril 2007 à 12:07
Juste un petit message pour dire que c'est pas la peine de demonter ceux qui propose des choses meme basique , car il faut bien commencer un jour et c'est justement en aidant les autres que l'on apprend aussi l'humilité....
Merci Bruno c'est super sympa..
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 sept. 2005 à 12:14
ah non ? pourtant avec un cours d'"échangisme" de ymca2003 (on ne se demande plus ce qu'il a fait de ses vacances...) en plus, ça pourrait donner du pas ordinaire.
BunoCS Messages postés 15392 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 septembre 2023 102
8 sept. 2005 à 11:59
Je pense que vous me comprendrez si je ne fais pas de mise à jour :)
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 sept. 2005 à 09:38
Allocation : malloc
Libération : delete
=> pas bon. Il ne faut pas mixer (surtout si c'est du C car delete c'est C++).
malloc et free n'aiment pas faire de l'échangisme avec new et delete.
BunoCS Messages postés 15392 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 septembre 2023 102
7 sept. 2005 à 20:42
Ok, merci de ta soluce.
Mais, entre nous, un débutant (qui ne prend pas en compte la performance de son code) préférera, non pas ma version, mais un code équivalent je pense. Mais ceci est personnel :)

@+ et merci de tes conseils

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.