IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Recherche dans un fichier (grep)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut Recherche dans un fichier (grep)
    Bonjour,

    Je voudrais creer un programme similaire a la commande "grep" de unix que je voudrais appeller "newgrep" ou :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    newgrep trucachercher fichier.c
    Imprimera tout les resultats dans la console et comptera les lignes trouvees.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    # include <stdio.h>
     
    int main ( int argc, char * argv [ ] )
    {
      FILE * fp;
      char buffer [ 81 ];
     
      if(argc != 3){
        printf("Usage : newgrep searchstr searchfile [-o outputfile]\n");
       }
     
      else {
        if ((fp = fopen(argv[2],"r")) == NULL) {
          printf ("\n Cannot open file specified.\n");
          exit(1);
         }
     
        while ( fgets ( buffer, 81, fp ) ) {
          fputs ( buffer, stdout );
        }
      }
      return 0;
    }
    Pour l'instant le code ne fait que lire un fichier et imprimer le resultat dans la console. Je ne sais pas comment modifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        while ( fgets ( buffer, 81, fp ) ) {
          fputs ( buffer, stdout );
        }
    De telle maniere a ce que le program interprete argv[1](trucachercher) en tant que chaine de caractere a chercher dans le fichier specifiee...

  2. #2
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Salut,

    Premierement faut savoir ce que tu veux faire exactement, car grep ne permet pas de chercher une chaine dans un fichier, ça permet de faire des recherches de chaines définies par des expressions regulieres (plusieurs syntaxes sont d'ailleurs proposées) dans un ou plusieurs fichiers ou sur l'entrée standard.
    C'est comme printf, ça sert pas à afficher une chaine, ça sert à afficher quelquechose suivant une chaine de format.

    Admettons que tu veuilles afficher les lignes où apparait exactement la chaine recherchée, tu pourrais utiliser strstr pour rechercher une chaine dans un autre.
    Un simple fgets ne suffira pas car tu pourras pas faire une recherche fiable sur des fichiers contenant des lignes de plus de sizeof buffer caractères. Un moyen serait d'utiliser realloc pour allouer et reallouer le buffer d'entrée (çe ne serait plus un tableau de char et il faudrait maintenir une variable contenant la taille de ce buffer).

  3. #3
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    Citation Envoyé par Gruik Voir le message
    Salut,

    Premierement faut savoir ce que tu veux faire exactement, car grep ne permet pas de chercher une chaine dans un fichier, ça permet de faire des recherches de chaines définies par des expressions regulieres (plusieurs syntaxes sont d'ailleurs proposées) dans un ou plusieurs fichiers ou sur l'entrée standard.
    C'est comme printf, ça sert pas à afficher une chaine, ça sert à afficher quelquechose suivant une chaine de format.

    Admettons que tu veuilles afficher les lignes où apparait exactement la chaine recherchée, tu pourrais utiliser strstr pour rechercher une chaine dans un autre.
    Un simple fgets ne suffira pas car tu pourras pas faire une recherche fiable sur des fichiers contenant des lignes de plus de sizeof buffer caractères. Un moyen serait d'utiliser realloc pour allouer et reallouer le buffer d'entrée (çe ne serait plus un tableau de char et il faudrait maintenir une variable contenant la taille de ce buffer).
    C'est ce que je veux faire, mais pas aussi sophistiquee que "grep" d'Unix.
    A ce que j'ai compris:
    Il faut donner une variable au buffer de facon a ce qu'on lui realloue une memoire suffisante apres chaque recherche.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char buffer[search];
     
    buffer = malloc(81);
     
    strcpy(buffer, search);
     
    buffer = realloc(buffer, sizeof(search));
    La lecture se fera donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        while ( fgets ( buffer, 81, fp ) ) {
          strstr( buffer, argv[1]);   // trouver argv[1] dans buffer (ce qui a ete lu)
          fputs ( buffer, stdout );   // imprimer le nouveau contenu de buffer ??
     
        }
    Ou est l'erreur ?

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        while ( fgets ( buffer, 81, fp ) ) {
          strstr( buffer, argv[1]);   // trouver argv[1] dans buffer (ce qui a ete lu)
          fputs ( buffer, stdout );   // imprimer le nouveau contenu de buffer ??
     
        }
    Ou est l'erreur ?
    Il faut lire la doc de strstr() et s'intéresser à son retour...

    Ton mécanisme de réallocation est plus que douteux... Le tableau ne doit jamais déborder.

  5. #5
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    Ajouter un if a regle le probleme. En principe avec ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        while ( fgets ( buffer, sizeof(buffer), fp ) ) {
          if(strstr( buffer, argv[1])){
           fputs ( buffer, stdout );}
     
        }
    Le resultat est bon, toute les lignes recherche sont affichees. Mais est ce que c'est efficace ? (efficient)

    Comment faire pour afficher les resultats en majuscules ? J'ai essaye avec toupper() de cette maniere:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fputs(toupper(buffer), stdout);
    Mais ca na pas l'air de plaire au compiler.

    Autre question, si je veux compter les lignes de resutats et de chaine caracteres trouvees, je procede comment ?

    Merci

    PS: pour la reallocation, j'ai prefere donner a 'buffer' 250, les lignes ne depasseront pas cette taille.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    LA PROGRAMMATION N'EST PAS DE METTRE DES INSTRUCTIONS AU HASARD ET D'ESPERER QUE CA MARCHE !!!!


    Lis la doc de toupper avant de demander de l'aide.... Et tu verras que tu fais n'importe quoi..

    D'autre part, ton test de fgets n'est pa la meilleur manière d'écrire, mais plutôt

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( fgets(...) != NULL )

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    Ajouter un if a regle le probleme. En principe avec ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        while ( fgets ( buffer, sizeof(buffer), fp ) ) {
          if(strstr( buffer, argv[1])){
           fputs ( buffer, stdout );}
     
        }
    Le resultat est bon, toute les lignes recherche sont affichees. Mais est ce que c'est efficace ? (efficient)
    C'est pas très efficace. Un automate traitant les caractères un par un devrait êre meilleur, mais c'est un peu plus complexe. Il y a aussi le problèmes des mots 'coupés' (sur 2 lignes...)
    Comment faire pour afficher les resultats en majuscules ? J'ai essaye avec toupper() de cette maniere:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fputs(toupper(buffer), stdout);
    Mais ca na pas l'air de plaire au compiler.
    toupper(), comme l'indique la doc que tu aurais du lire au lieu de faire n'importe quoi, ne traite qu'un caractère, pas une chaine. Je te laisse écrire la fonction de traitement de chaine.
    Autre question, si je veux compter les lignes de resutats et de chaine caracteres trouvees, je procede comment ?
    Tu définis un compteur initialisé à 0, puis tu l'incrémentes de 1 à chaque fois que la condition correspondante est vérifiée. (C'était trop dur ! Je me suis pété 3 neurones en cherchant ça !)

Discussions similaires

  1. Améliorer la recherche dans un fichier?
    Par abdmaa dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 09/05/2005, 13h09
  2. [LG]Runtime Error lors d'une recherche dans un fichier
    Par Fraynor dans le forum Langage
    Réponses: 2
    Dernier message: 15/03/2005, 22h51
  3. Rechercher dans un fichier avec emacs
    Par ggnore dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 24/11/2004, 10h28
  4. recherche dans un fichier xml (castor)
    Par pingoui dans le forum Format d'échange (XML, JSON...)
    Réponses: 8
    Dernier message: 06/09/2004, 14h28
  5. [LG]rechercher dans un fichier texte
    Par BadFox dans le forum Langage
    Réponses: 11
    Dernier message: 01/12/2003, 15h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo