/* Mini-Grep */
Autor: Chris | Publicado: 2011-11-04T14:14:00-07:00


Descrição/Sobre:
Grep (global / regular expression / print) é um programa executado pela linha de comando do Linux. Esse programa consiste em buscar uma expressão (uma palavra, por exemplo) em arquivos. O Grep original imprime na saída padrão todas as linhas em que ocorreram a expressão mencionada.
Este é um código que funciona de forma parecida, mas reduzida, por isso mini-grep. O uso pela linha de comando é: [programa] [opções] [expressão] [arquivo]. Lembrando que programa é o executável do mini-grep e o arquivo deverá ser o nome com sua extensão.

Código:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

FILE* abreArquivo(char caminho[], char modo[]){
    FILE *f = fopen(caminho, modo);
    
    if(!f){
           printf("ERRO: O arquivo nao existe\n&lt;ENTER&gt;");
           getchar();
           exit(0);
    }
    return f;
}


void fechaArquivo(FILE *f){
    if(fclose(f)){
        printf("ERRO: Problemas ao fechar o arquivo\n&lt;ENTER&gt;");
        getchar();
     }
}

char* leLinha(FILE *f, char *aux){
     int cont = 0;
     
     do{
        if(aux == NULL){
           aux = (char*) malloc(sizeof(char));
           if(!aux){
              printf("ERRO: erro ao alocar memoria\n&lt;ENTER&gt;");
              getchar();
              exit(0);
           }
        }
        else{
           aux = (char*) realloc(aux, (cont+1) * sizeof(char));
           if(!aux){
              printf("ERRO: erro ao realocar memoria\n&lt;ENTER&gt;");
              getchar();
              exit(0);
           }
        }

        fscanf(f, "%c", &amp;aux[cont]);
        cont++;
     }while(aux[cont-1] != 10 &amp;&amp; aux[cont-1] != 0);
     aux[cont-1] = 0;
     
     return aux;
}

void buscaPalavra(FILE *f, char *palavra, int op){
    int linha = 0;
    
    if(!op) strupr(palavra);
    
    while(!feof(f)){
       char *aux = NULL;
       
       aux = leLinha(f, aux);
       linha++;
       if(!op) strupr(aux);
       
       if(strstr(aux, palavra)){
          printf("%d: %s\n", linha, aux);
          printf("\n&lt;ENTER&gt;");
          getchar();
          free(aux);
          aux = NULL;
          return ;
       }
       
       free(aux);
       aux = NULL;
    }
    
    printf("Palavra nao encontrada");
    printf("\n\n&lt;ENTER&gt;");
    getchar();
    
}

int parametrosCorretos(int argc, char *argv[]){
    if(argc &lt; 3 || argc &gt; 4){
       printf("\nUso correto: [%s] [opcoes] [palavra] [nome_do_arquivo]", argv[0]);
       printf("\n\n\n&lt;ENTER&gt;");
       getchar();
       return 0;
    }
    
    if(argc == 4)
       if(strcmp(argv[1], "-i")){
          printf("\nOpcao incorreta.\n\nLista de opcoes validas:\n\n");
          printf(" [-i]\tnao diferenciar maiusculas de minusculas");
          printf("\n\n\n&lt;ENTER&gt;");
          getchar();
          return 0;
       }
    return 1;
}

int main(int argc, char *argv[]){
    FILE *f = NULL;
    
    system("cls");
    if(!parametrosCorretos(argc, argv)) exit(0);
    
    if(argc == 4){
       f = abreArquivo(argv[3], "r");
       buscaPalavra(f, argv[2], 0);
    }
    else{
       f = abreArquivo(argv[2], "r");
       buscaPalavra(f, argv[1], 1);
    }
    
    fechaArquivo(f);
    return 0;
}






Primeiro testamos se os parâmetros foram passados de maneira correta e para isso chamamos a função 'parametrosCorretos'. Se o programa foi chamado de forma correta, abrimos o arquivo(se ele existir) e buscamos a palavra a partir da função 'buscaPalavra'. Como não sabemos o tamanho da linha a princípio, se usássemos um array já com suas dimensões definidas poderíamos cair em uma situação em que a linha é maior que este array. Resolvemos este problema com a função 'leLinha', que vai alocando a memória caractere a caractere. Por fim retorna o endereço da linha. O programa para na primeira ocorrência da expressão, e se a mesma não for encontrada exibe uma mensagem no final. :)




---
You can do it!