codigo en c errores

Iniciado por rick520, 11 Diciembre 2020, 23:24 PM

0 Miembros y 1 Visitante están viendo este tema.

rick520

no puedo compilarlo, creo que el error esta en el carga con los punteros, pero nose como arreglarlo


#include <stdio.h>
#include <string.h>
#define N 10000

typedef struct traductor{
   char espanol[20];
   char ingles[20];
   int num;
 }traductor;
traductor T[N];
traductor Auxi;


void CARGA(struct traductor T[N], int *i){


   FILE *archivo1=fopen("espaingl.dat","r");
   if(archivo1 == NULL){
       printf("\nError en la apertura del archivo\n");
   return;
   }
   while(!feof(archivo1)){
           fscanf(archivo1,"%s  %s %d",T[*i].espanol, T[*i].ingles, T[*i].num);
           *i=*i+1;
  }
   fclose(archivo1);
}

int busqueda_dicotomica (struct traductor T[N], int *i, char pal_espanol[21]) {
   int min, max, medio;
   char palabra;
   min=0;
   max= *i-1;
   medio= (min + max)/2;
   while (strcmp(T[medio].espanol, pal_espanol)!=0 &&min<=max) {
           if (strcmp(pal_espanol, T[medio].espanol) <0){
               max=medio-1;}
           else{
               min=medio+1;}

           medio= (min+max)/2; //fin si
   }//fin mientras
   if (strcmp(T[medio].espanol, pal_espanol) ==0)
       return (medio); //se encontro la nueva palabra en el listado
   else
       return -1; //no se encontro la palabra en el listado
   //finsi

}//fin busqueda dicotomica

int MENU(){
   int op;
   printf("--------------------------\n");
   printf("BIENVENIDO AL TRADUCTOR\n\n");
   printf("Elija la opcion que desee\n");
   printf("(1)Ingles a Espanol\n");
   printf("(2)Espanol a Ingles\n");
   printf("(0)Cerrar");
   printf("\n--------------------------\n");
   printf("Opcion: ");
   scanf("%d", &op);
   while(op<0 || op>2){
       printf("Error- opcion inexistente, elija entre 0 y 2: ");
       scanf("%d", &op);
   }
}

int MENU1(){
   char w;
   printf("\nElija opcion\n");
   printf("T - Traducir al espanol\n");
   printf("A - Agregar palabra\n");
   printf("M - Mas buscadas\n");
   printf("V - Volver\n");
   printf("Opcion: ");
   scanf(" %c",&w);
   while(w!='t' && w!='a' && w!='m' && w!='v'){
       printf("Error- Elija T, A, M o V: ");
       scanf(" %c",&w);
   }
}

int MENU2(){
   char q;
   printf("\nElija opcion\n");
   printf("T - Traducir al ingles\n");
   printf("A - Agregar palabra\n");
   printf("M - Mas buscadas\n");
   printf("V - Volver\n");
   printf("Opcion: ");
   scanf(" %c",&q);
   while(q!='t' && q!='a' && q!='m' && q!='v'){
       printf("Error- Elija T, A, M o V:");
       scanf(" %c",&q);
   }
}

void tradu(int opc, int *i) {
    int p, j, temp,des,band1,band,medio;
    char aux[20], la[20];

    CARGA(T, &i);
    temp = 0;

    printf ("\nIntroduce la palabra que desea buscar: ");
    fflush(stdin);
    fgets(aux,N,stdin);
    cambio (aux);
    if(opc==1){
       band=0;
       while(band==0){
           for (p=0 ; p<*i; p++) {
               j = strcmp (aux, T[p].ingles);
               if(j==0){
                   printf("La traduccion de %s es %s\n", T[p].ingles, T[p].espanol);
                   T[p].num=T[p].num+1;

                   band++;
               }
           }
       }
               if(band!=0){
                   printf("La palabra no se encontro, Si desea agregarla marque 1");
                   scanf(" %d", &des);
                   if(des==1){
                           strcpy(T[*i].ingles, aux);
                           printf("Ingrese la traduccion: ");
                           scanf(" %s", &la);
                           strcpy(T[*i].espanol, la);
                           T[*i].num=0;
                           *i=*i+1;
                   }
               }
    }
    else {
           band1=0;
           while(band1==0){
                   medio=busqueda_dicotomica(T, &i, aux);
                       j = strcmp (aux, T[medio].espanol);
                       if (j == 0) {
                           printf ("La traduccion de %s es %s\n", T[medio].espanol, T[medio].ingles);
                           band1++;
                           T[medio].num=T[medio].num+1;
                       }

           }
           if(band!=0){
               printf("La palabra no se encontro, Si desea agregarla marque 1 o cero para volver");
               scanf(" %d", &des);
               if(des==1){
                       strcpy(T[*i].espanol, aux);
                       printf("Ingrese la traduccion: ");
                       scanf(" %s", &la);
                       strcpy(T[*i].ingles, la);
                       T[*i].num=0;
                       *i=*i+1;
               }
           }
}
}

void cambio (char palabra[20]) {
   int i;

   for(i=0 ; i<N ; i++){
       if (palabra[i] == '\n'){
           palabra[i] = '\0';
       }
   }
}

void Agregar (int opc, int *i){
  char Npal, la;
  int p, j,bandera,bandera1,x,c,y,posicion,maximo;
   CARGA (T, &i);
   if (opc ==1){
           printf("Ingrese la palabra que desea agregar");
           scanf (" %s",&Npal );
           bandera==0;
               for(p=0 ; p<*i; p++){
                   j = strcmp (Npal, T[p].ingles);
                   if(j==0){
                       printf("La palabra ya existe");
                       bandera++;
                   }
               }
           if(bandera!=0){
              strcpy(T[*i].ingles, Npal);
                       printf("Ingrese la traduccion: ");
                       scanf(" %s",la);
                       strcpy(T[*i].espanol, la);
                       T[*i].num=0;
                       *i=*i+1;
           }
   }
       if (opc == 2){
           printf("Ingrese la palabra que desea agregar");
           scanf (" %s",&Npal );
           bandera1=0;
           for (c=0 ; c<*i; c++) {
               j = strcmp (Npal, T[c].espanol);
               if(j==0){
                   printf("La palabra ya existe");
                   bandera1++;
               }
           }
               if(bandera1!=0){
                   strcpy(T[*i].ingles, Npal);
                       printf("Ingrese la traduccion: ");
                       scanf(" %s", &la);
                       strcpy(T[*i].ingles, la);
                       T[*i].num=0;
                       *i=*i+1;
               }
           }
           //ordenamiento

           for(x=0;x<*i-1;x++){
               maximo= T[x].num;
               posicion=x;
               for(y=x+1;y<*i;y++){
                   if(T[x].num >maximo){
                       maximo=T[x].num;
                       posicion=y;
                   }
               }
             Auxi=T[posicion];
             T[posicion]=T[x];
             T[x]=Auxi;
           }
       }

void MasBuscada(int i){
   int x,c,y,posicion,maximo;
   for(x=0;x<i-1;x++){
               maximo= T[x].num;
               posicion=x;
               for(y=x+1;y<i;y++){
                   if(T[x].num >maximo){
                       maximo=T[x].num;
                       posicion=y;
                   }
               }
             Auxi=T[posicion];
             T[posicion]=T[x];
             T[x]=Auxi;
           }
   printf("Las diez palabras mas buscadas fueron: \n");
   for(c=0;c<10;c++){
       printf("%s %s %d \n",T[c].espanol, T[c].ingles, T[c].num );
   }
}

int main(void){
   struct traductor T[N];
   int opc,i=0;
   char men1,men2;

   CARGA(T,&i);
   opc=MENU();

   while(opc!=0){
           switch(opc){
               case 1:
                   printf("Elijio opcion: 1 \n\n");
                   men1=MENU1();
                   while(men1!='v'){
                       switch(men1){
                           case 't':
                               tradu(opc,&i);
                           break;
                           case 'a':
                             Agregar (opc, &i);
                           break;
                           case 'm':
                              MasBuscada(i);
                           break;
                       }
                   men1=MENU1();
                   }
               break;
               case 2:
                   printf("Elijio opcion: 2\n\n");
                   men2=MENU2();
                   while(men2!='v'){
                       switch(men2){
                           case 't':
                               tradu(opc,&i);
                           break;
                           case 'a':
                              Agregar (opc, &i);
                           break;
                           case 'm':
                               MasBuscada(i);
                           break;
                       }
                   men2=MENU2();
                   }
               break;
           }
           opc=MENU();
   }
   printf("\n\nUsted ha finalizado el Programa\n");
return 0;
}




MOD: El código debe estar publicado entre etiquetas de Código GeSHi

K-YreX

Lo primero mencionar que el código debe ir entre etiquetas de Código GeSHi. Las puedes seleccionar mediante el desplegable que hay encima del cuadro de texto o escribiéndolas tú manualmente.

Veo bastantes cosas mejorables (algunos son errores y otros no pero convendría corregirlo también).
Te pondré un indicador según el mensaje: Consejo (no da errores pero es mejor cambiarlo) | Aviso (puede dar errores según el caso) | Error (esto no funciona bien)
Voy mencionando según vaya viendo cosas:
  • Consejo: Por convenio las estructuras se suelen definir en UpperCamelCase -> Traductor.
  • Consejo: No utilizar variables globales. Es mejor crear las variables en la función main() y usar parámetros para pasar los datos a otras funciones (cosa que haces).
  • Consejo: Las funciones por convenio en lowerCamelCase -> carga(), busquedaDicotomica(),...
  • Consejo: Al utilizar typedef para definir la struct, ya no es necesario que utilices la palabra struct cada vez que la quieras hacer referencia.
  • Consejo: Al pasar arrays como parámetro no hace falta indicar la primera dimensión. Es obligatorio indicar todas las dimensiones excepto la primera. Es un número innecesario que tendrás que estar cambiando cada vez que hagas una modificación de tamaño.
  • Consejo: Utiliza constantes para todos los tamaños. Evita utilizar números sueltos que no aporten información y que haga más complicado la modificación de tamaños.
  • Aviso: En la función carga() no tienes en cuenta que haya más registros en el fichero que espacio en el array.
  • Aviso: Utilizar fscanf() o scanf() no es recomendable para cadenas de texto char[]. Lo recomendable es utilizar fgets().
    fgets(char *array, int limite_de_caracteres_a_copiar, FILE *fichero);


    Aquí me surge una duda y es: ¿por qué utilizas unos arrays de longitud 20 y otros de longitud 21? Y si la respuesta va a ser que la longitud es 21 para que entren los 20 que tiene el original + el caracter de fin de cadena, decir que el caracter de fin de cadena también lo tienen los de longitud 20 (lo tienen todas las cadenas char[]).
    Dicho esto, seguimos...


  • Consejo: No modificar el valor de i en busquedaDicotomica() por lo que no es necesario pasarlo como puntero. Hacerlo, además, facilita errores si modificas el valor de i sin querer.
  • Consejo: No utilizas la variable <palabra> en busquedaDicotomica().
  • Error: En la función Menu() no devuelves nada y tienes que devolver un int.
  • Error: En la función Menu1() tampoco devuelves nada. Además aunque C trabaja internamente igual con int/char es mejor devolver un char para que se entienda mejor.
  • Error: En la función Menu2() más de lo mismo.
  • Error: En la función tradu() recibes un int* (i) y luego lo pasas a carga() con &i por lo que en realidad estás pasando a carga() un int** cuando tiene que recibir un int*.
  • Aviso: fflush() está diseñada para limpiar el buffer de salida (stdout), no el de entrada (stdin). No suele dar problemas aunque nada impide que lo haga. Deberías limpiar el buffer de entrada después de cada uso con, por ejemplo:
    while(getchar() != '\n');
    (Es importante usar esto cuando sepas que el buffer tiene algún contenido porque de estar vacío, el programa no continuará hasta que no introduzcas un enter)
  • Error: En la función tradu() estás llamando a la función cambio() y esta todavía no existe. Si se crean las funciones sin definir los prototipos no se pueden usar funciones en líneas en las que aún no están definidas. Es por esto que o se organiza bien el orden de las funciones o es mejor definir antes del main() los prototipos y después del main() el cuerpo de las funciones.
  • Consejo: El código debería estar mejor indentado y especialmente en bloques grandes.
  • Error: Línea 122 -> Si encuentras la palabra, incrementas el valor de <band> y después te indicará que la palabra no se encontró cuando no es cierto.
  • Aviso: En <aux> puedes guardar una palabra de hasta 10000 caracteres (cosa que no creo que quieras hacer). Si luego la copias en un array de longitud 20 puedes tener problemas si <aux> tiene más de 20 caracteres. La función que debes usar es strncpy() para especificar el límite de caracteres a copiar.
  • Consejo: En la línea 138 guardas en <medio> (que se llamaría mejor <encontrado> o <indiceEncontrado>) el valor del índica en el que está esa palabra o -1 si no estaba la palabra. No tienes que volver a comprobarlo otra vez.
  • Error: El bucle de la línea 137 es infinito si no se encuentra la palabra.
  • Consejo: La función cambio() no es necesaria y además no debes comprobar cada índice. Es suficiente con que después de usar un fgets() copies:

    if(palabra[strlen(palabra)] - 1] == '\n') palabra[strlen(palabra) - 1] = '\0';
    else while(getchar() != '\n');

    Este bloque de código funciona muy bien junto y engloba dos funciones. Por un lado elimina el salto de línea del enter final y por otro lado deja el buffer de entrada siempre limpio.

    La función Agregar() no la he mirado con detenimiento pero así por encima decir que al llamar a carga() otra vez vas a volver a incluir todo el contenido del fichero de nuevo. Además tienes el mismo problema al pasar int** en vez de int*.
    El ordenamiento que haces sería un muy buen candidato a una función aparte. Además veo que ordenas según el valor de num por lo que tu búsqueda dicotómica no va a funcionar correctamente pues busca por nombre, no por número.
    Además cuando llamas a masBuscada() vuelves a ordenarlo otra vez...

    Bueno y ya llegar al main() y encontrarme con otro <T[]>... :-\ :-\
    Una mejor manera de repetir los menús es usar un do-while() en vez de usar un while() y llamar al menú antes de empezar y al final de este otra vez.

    Creo que con todo lo que he puesto ya tienes para hacer correcciones un buen rato. Además aunque te las haya puesto en un único sitio hay algunas que las he visto varias veces por lo que no servirá si te limitas a cambiar las cosas en el orden que las puse sino que tendrás que revisar bien tu código.
    Además veo el código un poco mal estructurado y en muchas ocasiones que las funciones sean tan grandes y los nombres de las variables tan poco descriptivos hace casi imposible el seguimiento del funcionamiento.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;