Segundo parcial ICom-2003

Nota: Respete los prototipos de las funciones y no olvide el pseudocódigo para cada una de ellas.

Motivación: El programa 'grep' de linux, ejecutado con: 'grep string file' imprime en pantalla todas las lineas del archivo 'file' en las que aparece el arreglo de caracteres 'string' (pruebelo). Pero a veces se necesita más información que la contenida en esa única linea, por lo que se desea imprimir las 'n' lineas más arriba y abajo de dicha linea, es decir una 'Ventana' de 'cantlineas'=2*n+1 lineas, centrada en la aparición de 'string'.

En el archivo ej.c está definida una estructura que permite almacenar un arreglo dinámico de strings (linea), junto con su tamaño (cantlineas). La idea es utilizar esta estructura para guardar varias lineas consecutivas de un archivo, de ahí el nombre Ventana. La estructura también contiene la información de qué número de línea del archivo corresponde al primer string del arreglo (numlinea0) y a partir de el deducir el número de línea del resto. Corriendo las lineas dentro del arreglo (y agregando nuevas extraidas del archivo) podemos desplazar esta ventana a lo largo del mismo.
Para manipular esta estructura se requiere la implementación de las siguientes funciones:

    Ventana * creaVentana( int cantlineas );
    /* Crea una nueva Ventana que pueda contener cantlineas lineas, retornando su puntero.
    Inicialmente el arreglo de strings está inicializado con NULL y el valor de numlinea en un valor negativo, de forma que podemos pensar que la nueva ventana se encuentra posicionada justo antes del comienzo del archivo.*/

    void destruyeVentana( Ventana * pv );
    /* Se encarga de liberar todo el espacio de memoria asociado con la ventana apuntada por pv*/

    void imprimeVentana( Ventana * pv );
    /* Imprime todas las líneas de la ventana apuntada por pv, cada una precedida del número de línea que le corresponde en el archivo. Los límites de la ventana deben ser claramente visibles en la impresión */

    void pushVentana( Ventana * pv, char * s );
    /* Corre todas las líneas en 1, eliminando la línea 0 y colocando el string s que se le pasa como argumento en la última línea. Debe modificar también numlinea0 apropiadamente */

    char * avanzaVentana( Ventana * pv, FILE *pf );
    /* Lee una linea del archivo apuntado por pf y la coloca en la Ventana apuntada por pv. Debe retornar la línea leída o NULL en caso de llegar al final de archivo */

    char * GetLine( FILE * pf );
    /* Lee una línea de a lo sumo MAXLINE caracteres del archivo apuntado por pf, elimina el "\n" del final ( si lo hubiere ) y la retorna como un nuevo string. */

    int buscaVentana( FILE *pf, char *busco, Ventana *pv );
    /* Avanza la ventana hasta encontrar el string busco en la línea central de la ventana. Si lo encuentra retorna el número de línea que le corresponde en el archivo, si no retorna -1 */

En el archivo ej.c podrá encontrar la impelmentación de la función creaVentana a modo de ejemplo. También se provee un main para el uso típico de esta estructura y sus funciones: pide al usuario el tamaño de la ventana, el nombre del archivo y el string a buscar (sin tenerle mucha paciencia). Busca todas las ocurrencias de ese string, imprimiendo las ventanas centradas en la línea donde se encontró el string. Este programa es una especie de extensión del comando grep del sistema. Su trabajo es implementar las funciones que faltan.

Nota: puede utilizar funciones de la biblioteca standard tales como strlen, strstr, strcpy, fgets, etc. (no, etc no es una función de la biblioteca standard). Utilice el man para ver en que le pueden ayudar. Recuerde que también puede usar alguna de las funciones que le pedimos para facilitar la implementación de otras ; -)