Páginas

sexta-feira, 4 de novembro de 2011

/* Mini-Grep */


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 <stdio.h>
#include <stdlib.h>
#include <string.h>

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


void fechaArquivo(FILE *f){
    if(fclose(f)){
        printf("ERRO: Problemas ao fechar o arquivo\n<ENTER>");
        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<ENTER>");
              getchar();
              exit(0);
           }
        }
        else{
           aux = (char*) realloc(aux, (cont+1) * sizeof(char));
           if(!aux){
              printf("ERRO: erro ao realocar memoria\n<ENTER>");
              getchar();
              exit(0);
           }
        }

        fscanf(f, "%c", &aux[cont]);
        cont++;
     }while(aux[cont-1] != 10 && 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<ENTER>");
          getchar();
          free(aux);
          aux = NULL;
          return ;
       }
       
       free(aux);
       aux = NULL;
    }
    
    printf("Palavra nao encontrada");
    printf("\n\n<ENTER>");
    getchar();
    
}

int parametrosCorretos(int argc, char *argv[]){
    if(argc < 3 || argc > 4){
       printf("\nUso correto: [%s] [opcoes] [palavra] [nome_do_arquivo]", argv[0]);
       printf("\n\n\n<ENTER>");
       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<ENTER>");
          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!

Nenhum comentário:

Postar um comentário