info@mp2i-pv
Il s’agit dans ce TP de programmer une version simpliste de la
commande grep
.
Voici un extrait de la page de manuel de grep
:
NAME
grep, egrep, fgrep, rgrep - print lines matching a pattern
SYNOPSIS
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] -e PATTERN ... [FILE...]
grep [OPTIONS] -f FILE ... [FILE...]
DESCRIPTION
grep searches for PATTERN in each FILE. A FILE of “-” stands for
standard input. If no FILE is given, recursive searches examine the
working directory, and nonrecursive searches read standard input. By
default, grep prints the matching lines.
Dans ce TP, on va se contenter de motifs qui sont des chaînes de caractères et d’un texte.
Écrire une fonction
int *occ_droite(const char *motif);
qui prend une chaîne de caractères en argument et renvoie un tableau
de la taille le nombre de valeurs du type char
, qui contient la
dernière occurence de (char) i
dans la case d’indice i
, et -1 si
(char) i
n’apparaît pas dans le motif.
On considère le type liste chaînée:
struct liste_occ {
int occ; //indice de début d'une occurence
struct liste_occ *suite; //occurences suivantes
};
Écrire une fonction
struct liste_occ *boyer_moore(
FILE *fichier, //fichier à disséquer
char *texte, //tampon de texte courant
const char *motif, //motif à chercher
int debut_texte, //position de début dans le tampon
int courante_fichier, //position courante du texte
int *droite); //occurences les plus à droite
qui renvoie la liste des indices de début d’occurences du motif dans le texte, en utilisant l’algorithme de Boyer-Moore.
L’idée de base est la suivante: on a déjà lu un peu de texte dans le
fichier, il se trouve dans texte
, à partir de l’indice
debut_texte
. Si on n’a plus assez de texte, il faut en récupérer
dans le fichier
.
(fscanf
renvoie une constante macro-définie EOF
si on est au bout du fichier)
Écrire une fonction
void affichage(FILE *fichier, const char *motif)
qui affiche le texte en soulignant les occurences du motif.
Exemple, si cette fonction est exécutée sur le texte:
$ cat texte
ceci est une tentative en tente cartonnee
et meme une autre tentative sur
une autre ligne
on doit voir l’affichage suivant pour le motif ten
:
$ ./boyer_moore ten texte
ceci est une tentative en tente cartonnee
^^^ ^^^
et meme une autre tentative sur
^^^
une autre ligne
(On suppose que l’affichage de votre terminal se fait dans une police de largeur fixe.)
si cette fonction est exécutée sur le fichier:
$ cat texte
aaabaaaaaabaabaaabbbaaaaaabba
aabbaaaabb
on doit voir l’affichage:
$ ./boyer_moore aaa texte
aaabaaaaaabaabaaabbbaaaaaabba
^^^ ^^^^^^ ^^^ ^^^^^^
aabbaaaabb
^^^^
main
Faites en sorte qu’on puisse utiliser votre programme en spécifiant le motif et le nom du fichier en ligne de commande.