Recherche de chaîne de caractères dans un fichier

Description

Langage : C
Compilateur : Dev-C++ 4

Voici un programme qui permet d'indiquer un nom de fichier puis d'y rechercher une chaîne de caractères entrée par l'utilisateur.

Il utilise les notions suivantes :
- Fichiers : ouverture, lecture...
- Pointeurs

J'espère qu'il sera utile à d'éventuels débutants programmeurs.

Source / Exemple :


// SearchChar 2.0
// Auteur : oXo-Ig0r
// Contact : oxo_um@yahoo.fr
// Compilateur : Dev-C++ 4
// Description : recherche de chaîne de caractères dans un fichier

#include <stdio.h>
#include <string.h>

char mot[100],file_t[150],newtext[10000];

//Fonction d'entrée du mot recherché
int mot_recherche()
{
printf("\n\n> Mot recherch%c ?  ",130);
gets(mot);
fflush(stdin);
return 0;
}

//Fonction d'entrée du chemin du fichier
int file_c()
{
printf("> Chemin d'acc%cs du fichier texte ?  ",138);
gets(file_t);
fflush(stdin);
return 0;
}

//Fonction principale
main()
{
FILE *file;
char s_read[100];
int l_mot=0,l_file=0,ref=0,t,b,n,decal=0;

system("cls");
puts(".[ SearchChar 2.0 par Ig0r ].\n");

//Entrée du chemin du fichier
file_c();

 //Chemin du fichier trop long
 if(strlen(file_t)>150)
 {
 puts("\n> Chemin du fichier trop long : ERREUR");
 puts("> Appuyez sur une touche pour continuer...");
 getch();
 main();
 }

//Ouverture en BINAIRE
file=fopen(file_t,"rb");
 //Erreur d'ouverture
 if (file==NULL)
 {
 puts("\n> Impossible d'ouvrir le fichier : ERREUR");
 puts("> Appuyez sur une touche pour continuer...");
 getch();
 //On relance alors la fonction principale
 main();
 }
 //Si l'ouverture a réussi
 else
 {
  //Il s'agit ici de compter combien d'octets contient le fichier
  //Un caractère étant codé sur 1 octet on aura donc le nombre de caractères du fichier
  //Le pointeur est initialement au début du fichier
  //Tant que l'on atteint pas la fin du fichier,
  //On place dans n un bloc du fichier de la taille d'un entier et on incrémente l_file
  //Le pointeur avance ainsi à chaque tour de la taille d'un entier (4 octets)
  //Il faudra donc multiplier l_file par 4 pour avoir le nombre d'octets et non de groupes de 4 octets
  while(!feof(file))
  {
  n=getw(file);
  l_file++;
  }
  //On multiplie par 4 pour obtenir le nombre d'octets
  l_file=l_file*4;
  //On ferme
  fclose(file);
  //Ouverture en ASCII
  file=fopen(file_t,"r");
  printf ("> Fichier trouv%c (%d caract%cres) : OK",130,l_file,138);
 }

//Entrée du mot recherché
mot_recherche();
//Longueur du mot
l_mot=strlen(mot);
//Erreur si la longueur du mot est nulle
 if ((!l_mot)||(l_mot>100))
 {
 puts("\n> Mot incorrect (longueur nulle ou > 100) : ERREUR");
 puts("> Appuyez sur une touche pour continuer...");
 getch();
 main();
 }

 for (t=0;t<=(l_file-l_mot);t++)
 {
 //On place le pointeur à la position t (initialement nulle puis incrémentée)
 fseek(file,t,0);
 //On récupère l_mot caractères à partir de cette position
 //(autant de caractères que de caractères dans le mot)
 //Attention, le deuxième argument est 'l_mot+1' pour récupérer l_mot caractères !
 fgets(s_read,l_mot+1,file);
  //Si les chaînes mot et s_read sont identiques
  if(!(strcmp(s_read,mot)))
  {
  //On incrémente alors ref (qui contient le nombre de chaînes identiques trouvées)
  ref++;
  //Dans newtext, on place un symbole spécial juste avant le mot
  //Le pointeur de newtext sera en avance sur le pointeur de file à cause de ce symbole
  //C'est pourquoi on compense celà par l'entier decal incrémenté à chaque introduction du caractère spécial
  //*(newtext+t+decal)=2; -> caractère de code ASCII = 2

  • (newtext+t+decal)=2;
//On place après le symbole spécial un par un les caractères de s_read dans newtext for (b=0;b<l_mot;b++) {
  • (newtext+t+decal+1+b)=*(s_read+b);
} decal=decal+1; } else { //Si les chaînes sont diffèrentes, on recopie dans newtext //Et celà sans incrémenter decal ! for (b=0;b<l_mot;b++) {
  • (newtext+t+decal+b)=*(s_read+b);
} } } //Fermeture du fichier fclose(file); system("cls"); printf(".[ R%csultats ].\n",130); printf("\n> %d r%cf%crence(s) trouv%ce(s) pour '%s' .\n\n",ref,130,130,130,mot); puts("> Appuyez sur une touche pour voir le texte..."); getch(); system("cls"); //Affichage de newtext comportant des caractères spéciaux avant chaque mot trouvé puts(newtext); getch(); exit(); }

Conclusion :


Certains s'étonneront de voir que j'ouvre le fichier en binaire pour compter le nombre d'octets qu'il contient. Il s'avère qu'en l'ouvrant en mode texte, celà sautait des octets ce qui avait pour conséquence fâcheuse de placer le pointeur au mauvais endroit.

Merci de vous intéresser à ce code...

Codes Sources

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.