Consultas, desarrollo de programas y petición de presupuestos:

jueves, 12 de julio de 2012

examen 3: solución del alumno

//      wcjsbsan.c
//
//      Copyright 2011 julio
//
#include <stdio.h>
#include <string.h> // manejamos  cadenas (copiar, comparar)

// defino funciones....
void contar(int,int,int,char *);
// primer argumento es si cuento caracteres
// segundo argumento es si cuento palabras " ","\t","\n"
// tercero argumento es si cuento lineas  "\n"
// cuarto argumento es el nombre del archivo



int main(int argc, char **argv)
{
    // vemos los argumentos que nos han introducido....

    int c=0; // contador
    char archivo[256]; // guarda el nombre del archivo: esto es una limitacion (ver comentario final)
                                 // posible mejora: int posicion_nombre_archivo=0
                                 // guarda donde esta el archivo
en los argumentos

   // estas variables hacen una funcion de "interruptores"
    int contarpalabra=0; // si vale 0 no las contará, si vale 1  contara palabras
    int  contarlinea=0;// si vale 0 no las contará, si vale 1 contara lineas
    int contarcaracter=0; // si vale 0 no las contará, si vale 1 contara caracteres
  


   int errores=0;//contar errores (introduccion de parametros no validos

    while (c<argc) {
        printf("Argumento nº %d, es el %s \n",c,argv[c]);
        c++;
    }

    // reviso cada argumento, si la primera letra es un - (guion),
    // se trata de un argumento a analizar, sino es el nombre del archivo a analizar...

    c=1;
    while (c<argc) {
        if (argv[c][0]=='-') {
            //se trata de un argumento a analizar
            if (strcmp(argv[c],"-w")==0) {
                contarpalabra=1;
            } else {

                if (strcmp(argv[c],"-l")==0) {
                    contarlinea=1;
                } else {
                    if (strcmp(argv[c],"-c")==0) {
                        contarcaracter=1;
                    } else {
                        if (strcmp(argv[c],"-wl")==0) {
                            contarpalabra=1;
                            contarlinea=1;
                        } else {
                            if (strcmp(argv[c],"-lw")==0) {
                                contarpalabra=1;
                                contarlinea=1;
                            } else {
                                if (strcmp(argv[c],"--lines")==0) {
                                    contarlinea=1;
                                } else {
                                    if (strcmp(argv[c],"--words")==0) {
                                        contarpalabra=1;
                                    } else {
                                        // en caso contrario las combinaciones de letras no valdrían...
                                        fprintf(stderr, "%s: %s: Opcion no valia\n", argv[0], argv[c]);
                                        errores++;
                                    }
                                }
                            }
                        }
                    }
                }
            }





        } else {
            //sera el nombre del archivo
            if (argc>0) {
                strcpy(archivo,argv[c]); // ver comentario final,
                                                     // mejora: posicion_nombre_archivo=c;
                break;
            } else {
                fprintf(stderr, "%s: %s: No se ha especificado nombre de archivo valido\n", argv[0], argv[0]);
            }
        }
        c++;
    }

    if (errores!=0) {
        return 1;
    }

    if (argc==2) {
        //significa que solo ha escrio el comando y el nombre de archivo
        //tenemos que ejecutar -w -l -c
        contarpalabra=1;
        contarlinea=1;
        contarcaracter=1;
    }

    fprintf(stdout, "wcjsb contara del archivo: %s\n",archivo);



    if (contarlinea==1) {
        fprintf(  stdout, "contara lineas\n");
    }

    if (contarpalabra==1) {
        fprintf(  stdout, "contara palabras\n");

    }
    if (contarcaracter==1) {
        fprintf(  stdout, "contara caracteres\n");
    }
  // podiamos llamar sin usar la variable archivo de esta manera:
  //    contar(contarcaracter,contarpalabra,contarlinea,argv[posicion_nombre_archivo]);
    contar(contarcaracter,contarpalabra,contarlinea,archivo);
    return 0;
}

void contar(int caracter,int palabra,int linea, char *archivo)
{
    int numero_caracter=0;
    int numero_palabra=0;
    int numero_linea=0    ;
    FILE *pf;
    char letra;
    char letraAnterior;
    int errores=0;


    if((pf=fopen(archivo,"r"))==NULL) {
        fprintf(stderr, "%s: %s: No se puede abrir el fichero\n", archivo, archivo);
        errores++;


    } else {

        // Lee el primer caracter del archivo ¡porque es posible que el archivo este vacio!

        letra = fgetc(pf);
        letraAnterior = letra + 1; // asi nuestra letra anterior nos aseguramos que es distinta al anterior
        //numero_caracter++;

        // Mientras no sea fin de fichero
        while(!feof(pf)) {
            // tengo que analizar el caracter:
            if (palabra==1) {
                if ( ((letra==' ') || (letra=='\n') || (letra=='\t')) && (letra!=letraAnterior) ) {
                    // comprobramos que esta entre espacios y que no son espacios consecutivos (letra != letraAnterior)
                    numero_palabra++;
                }
            }

            if (linea==1) {
                if (letra=='\n') {
                    numero_linea++;
                }
            }
            numero_caracter++;
            letraAnterior = letra;
            letra = fgetc(pf);
        }
        // Cierra el archivo
        fclose(pf);

        // escribe resultado segun lo que nos hayan pedido....


        fprintf(  stdout, "-------------Resultados-------------\n");

        if (linea==1) {
            fprintf(  stdout, "Nº de  lineas: %d\n",numero_linea);
        }

        if (palabra==1) {
            fprintf(  stdout, "Nº de palabras: %d\n",numero_palabra);

        }

        if (caracter==1) {
            fprintf(  stdout, "Nº de caracteres: %d\n",numero_caracter);
        }

        fprintf(  stdout, "-------------  fin  -------------\n");

    }

}


Nota:
He corregido las condiciones que evaluaban la instruccion if que contaba las palabras, ahora va bien.

Mejora:
limitación al definir char archivo[256] (Comentada por los campañeros Luismiguel , Enrique y Beatriz)
El hecho de definir esta variable, es una limitación ya que estamos "limitando" operar con archivos (+ longitud ruta) que no superen los 255 caracteres (el ultimo tiene que estar servado a '\0').
Se puede evitar esto, creando una variable numerica int (por ejemplo llamandola posicion_nombre_archivo), que guarde la posicion del nombre del archivo dentro de la tabla de argv[] (normalmente, este argumento es el ultimo...):

argv[pocicion_nombre_archivo]

No hay comentarios:

Publicar un comentario en la entrada