Tema: funcion hash
Ver Mensaje Individual
  #1 (permalink)  
Antiguo 30/05/2010, 09:30
minette1988
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 10 meses
Puntos: 0
funcion hash

Hola, el siguiente programa crea un fichero, añade un nuevo registro, busca un cliente y ordena los clientes por su nombre:

Código C:
Ver original
  1. #include <stdlib.h>
  2.  
  3. #include <stdio.h>
  4.  
  5. #include <string.h>
  6.  
  7. struct client{
  8.  
  9.     char nom[10];
  10.  
  11.     char cognom[30];
  12.  
  13.     char adreca[30];
  14.  
  15.     int dia;
  16.  
  17.     int mes;
  18.  
  19.     int any;
  20.  
  21.     long int next; /* Punter al seguent registre */
  22.  
  23.     };
  24.  
  25.  
  26. main(){
  27.  
  28.  
  29.  
  30.     int op, i; /* Operacio del menu a excutar */
  31.  
  32.    
  33.  
  34.     void crear(); /* Modul de creacio del  fitxer */
  35.  
  36.     void escriu(); /* Modul que escriu nous registres al fitxer*/
  37.  
  38.     void cerca();  /* Modul per a cercar clients en el fitxer */
  39.     int n=12;
  40.  
  41.  
  42.         int ordenar();
  43.  
  44.         struct client *c; /* Variable per a llegir les dades */
  45.  
  46.  
  47.     do{ /* Bucle del programa principal, segons valor de op */
  48.  
  49.         do{
  50.  
  51.             printf("Opcions:\n");
  52.  
  53.             printf("1.- Crear el fitxer.\n");
  54.  
  55.             printf("2.- Afegir un nou registre\n");
  56.  
  57.             printf("3.- Cercar clients.\n");
  58.             printf("4.- Ordenar clients.\n");
  59.  
  60.             printf("5.- Sortir.\n");
  61.  
  62.             scanf("%d",&op);
  63.  
  64.         }while( (op < 1) && (op > 5) );
  65.  
  66.  
  67.  
  68.         switch(op){
  69.  
  70.             case 1: {crear();
  71.  
  72.                  break;}
  73.  
  74.             case 2: { escriu();
  75.  
  76.                  break;}
  77.  
  78.             case 3: {cerca();
  79.  
  80.                  break;}
  81.             case 4: {
  82.                     qsort(c, n, sizeof(c), ordenar);
  83.                        /*for(i=1; i <= n; i++)
  84.                           printf("%s\t%s\n", (c+i)->nom, (c+i)->cognom);*/
  85.  
  86.                  break;}
  87.  
  88.         }
  89.  
  90.     }while(op != 5);
  91.  
  92. } /* fi main */
  93.  
  94.         int ordenar();
  95.  
  96. void crear() {
  97.  
  98.  
  99.  
  100.     int i; /* Control de bucle */
  101.  
  102.     char f; /* Indica la fi del bucle de entrada de dades */
  103.  
  104.         struct client c; /* Variable per a llegir les dades */
  105.  
  106.     FILE *pf; /* Punter al fitxer a crear */
  107.  
  108.  
  109.  
  110.     void escriu();/* Llegeix els nous registres al fitxer */
  111.  
  112.  
  113.  
  114.     /* Creacio del fitxer */
  115.  
  116.  
  117.  
  118.     if((pf=fopen("corty","wb"))== NULL){
  119.  
  120.         printf("\n ERRADA AL CREAR EL FITXER CORTY \n");
  121.  
  122.         exit(1);
  123.  
  124.     }
  125.  
  126.  
  127.  
  128.     /* Escriptura dels registre primaris amb valors buits */
  129.  
  130.  
  131.  
  132.     c.nom[0]='b';/* Valor inicial del nom, sera buit el registre */     //}
  133.  
  134.     c.nom[1]='u';                                                       //}}
  135.  
  136.     c.nom[2]='i';                                                       //}}}}esto es igual strcpy(c.nom,"buit");
  137.  
  138.     c.nom[3]='t';                                                       //}}}
  139.  
  140.     c.nom[4]='\0';                                                      //}}
  141.  
  142.     c.next=-1;                                                          //}
  143.  
  144.  
  145.  
  146.  
  147.  
  148.     for (i=1; i<=12; i++){ /* Crea buits els registres primaris */
  149.  
  150.         printf("\nCrea registre %d\n",i);
  151.  
  152.         fwrite(&c,sizeof(c),1,pf);
  153.  
  154.     }
  155.  
  156.    
  157.  
  158.  
  159.  
  160.     fclose(pf); /* Tanca el fitxer que em creat */
  161.  
  162.  
  163.  
  164.     do{
  165.  
  166.         printf("Entrada de dades dels Clients:\n\n");
  167.  
  168.         escriu();
  169.  
  170.         printf("\n Un altre S/N: ");
  171.  
  172.         scanf("%1s",&f);
  173.  
  174.     }while((f != 'n') && (f != 'N'));
  175.  
  176.  
  177.  
  178. } /* Fi de crear */
  179.  
  180.  
  181.  
  182. void hueco(FILE *p, /* Punter al fitxer persona*/
  183.  
  184.     int x, /* Resultat del hash */
  185.  
  186.     struct client y /* Dades del nou registre */ ){
  187.  
  188.  
  189.  
  190.     int j; /* Per a veure si el registre triat pel hash es buit */
  191.  
  192.     long int k,m; /* Guarda a posicio de l'ultim registre de la llista */
  193.  
  194.     struct client c1; /* Valors dels registre anteriors al nou */
  195.  
  196.     char buit[5];
  197.  
  198.     buit[0]='b';
  199.  
  200.     buit[1]='u';
  201.  
  202.     buit[2]='i';
  203.  
  204.     buit[3]='t';
  205.  
  206.     buit[4]='\0';
  207.  
  208.  
  209.  
  210.     fseek(p,x*/*este asterisco es multiplicacion*/sizeof(c1),SEEK_SET);
  211.  
  212.     k=ftell(p);
  213.  
  214.     fread(&c1,sizeof(c1),1,p); /* Llegeix registre per a veure si es ple */
  215.  
  216.     j=strcmp(c1.nom,buit); /* Igual a valor inicial? */
  217.  
  218.     if (j == 0) /* Registre buit */
  219.  
  220.     {
  221.  
  222.         fseek(p,x*/*este asterispersonaco es multiplicacion*/sizeof(y),SEEK_SET);
  223.  
  224.         fwrite(&y,sizeof(y),1,p);
  225.  
  226.     }
  227.  
  228.     else { /* El registre primari no es buit */
  229.  
  230.     /* Ha de buscar l'ultim de la cadena */
  231.  
  232.         while(c1.next != -1){
  233.  
  234.             /* Situa el punter al seguent de la
  235.  
  236.             llista */
  237.  
  238.             fseek(p,c1.next,SEEK_SET);
  239.  
  240.             k=ftell(p); /* Guarda la posicio per
  241.  
  242.                     si es l'ultim */
  243.  
  244.                
  245.  
  246.             /* LLegeix el registre */
  247.  
  248.             fread(&c1,sizeof(c1),1,p);
  249.  
  250.         }
  251.  
  252.         /* Guardar el nou registre */
  253.  
  254.         fseek(p,0,SEEK_END); /* Va al final del
  255.  
  256.                       fitxer per guardar el
  257.  
  258.                       nou registre */
  259.  
  260.         m=ftell(p); /* Posicio de l'ultim de la
  261.  
  262.                 llista */
  263.  
  264.         fwrite(&y,sizeof(y),1,p);
  265.  
  266.         /* A d'assignar la posicio del l'ultim
  267.  
  268.         a seu predecessor */
  269.  
  270.         c1.next=m;
  271.  
  272.         /* Posicio del registre predecessor per a
  273.  
  274.         sobrescriure'l */
  275.  
  276.         fseek(p,k,SEEK_SET);
  277.  
  278.         fwrite(&c1,sizeof(c1),1,p);
  279.  
  280.         }
  281.  
  282. }
  283.  
  284.  
  285.  
  286. void cerca(){
  287.  
  288.  
  289.  
  290.     struct client c1; /* Llegeix el registres fins trobar el que volem */
  291.  
  292.     int x; /* Resultat del hash */
  293.  
  294.     char n[30]; /* Nom del client a cerca */
  295.  
  296.     int d,m,a; /* Data de neiximent del client a cerca */
  297.  
  298.     int j; /* Resultat de comparar les cadenes de noms de clinets */
  299.  
  300.     FILE *pf; /* Punter al fitxer */
  301.  
  302.     char f; /* Permet aturar el programa al mostrar les dades */
  303.  
  304.  
  305.  
  306.     void leelin(); /* Llegix cadenes amb espais en blanc dintre */
  307.  
  308.     int fhash(); /* Modul que calcula la funcio hash aplidar */
  309.  
  310.  
  311.  
  312.     if((pf=fopen("corty","rb"))== NULL){
  313.  
  314.         printf("\n ERRADA AL OBRIR EL FITXER CORTY \n");
  315.  
  316.         exit(1);
  317.  
  318.     }
  319.  
  320.     printf("\nCOGNOM del Client a CERCAR    :");
  321.  
  322.     leelin(&n,29);
  323.  
  324.     printf("\nData de Neiximent: ");
  325.  
  326.     printf("\nDIA: ");
  327.  
  328.     scanf("%d",&d);
  329.  
  330.     printf("\nMES: ");
  331.  
  332.     scanf("%d",&m);
  333.  
  334.     printf("\nANY: ");
  335.  
  336.     scanf("%d",&a);
  337.  
  338.     x=fhash(d,m,a); /* Calcula el hash */
  339.  
  340.     fseek(pf,x*sizeof(c1),SEEK_SET);
  341.  
  342.     do{
  343.  
  344.         fread(&c1,sizeof(c1),1,pf);
  345.  
  346.         j=strcmp(n,c1.cognom);
  347.  
  348.         if(j == 0) {/* Trobat */
  349.  
  350.             printf("\n%s  %s\n",c1.nom,c1.cognom);
  351.  
  352.             printf("\nPrem una tecla....");
  353.  
  354.             f=getchar();
  355.  
  356.             f=getchar();
  357.  
  358.         }
  359.  
  360.         fseek(pf,c1.next,SEEK_SET);
  361.  
  362.     }while ((c1.next != -1) && (j != 0 ));
  363.  
  364.  
  365.  
  366.     if (j != 0){
  367.  
  368.         printf ("\n NO TROBAT \n");
  369.  
  370.         printf("\nPrem una tecla....");
  371.  
  372.         f=getchar();
  373.  
  374.         f=getchar();
  375.  
  376.     }
  377.  
  378.  
  379.  
  380.     fclose(pf);
  381.  
  382.  
  383.  
  384. } /* fi de cerca */
  385.  
  386.  
  387.  
  388. int fhash(int day, int month, int year){ /* Calcula el hash en funcio de la
  389.  
  390.                     data de neiximent */
  391.  
  392.  
  393.  
  394.     int res; /* Resultat del hash */
  395.  
  396.  
  397.  
  398.     res=(day + month + year) % 12;  /* Formula del hash */
  399.  
  400.  
  401.  
  402.     return(res);  /* Torna al modul cridant el resultat del hash */
  403.  
  404.  
  405.  
  406. } /* Fi de fhash */
  407.  
  408.  
  409.  
  410. void escriu(){/*Modul que llegeix els nous registres i crida a hueco*/
  411.  
  412.  
  413.  
  414.         struct client c; /* Variable per a llegir les dades */
  415.  
  416.     FILE *pf; /* Punter al fitxer a personacrear */
  417.  
  418.     int i; /* Pren el valor tornat per la funcio fhash */
  419.  
  420.    
  421.  
  422.     int fhash(); /* Modul que calcula la funcio hash aplidar */
  423.  
  424.     void leelin(); /* Llegix cadenes amb espais en blanc dintre */
  425.  
  426.     void hueco(); /* Escriu el nou registre al fitxer */
  427.  
  428.  
  429.  
  430.     if((pf=fopen("corty","rb+"))== NULL){
  431.  
  432.         printf("\nERRADA AL OBRIR FITXER\n");
  433.  
  434.         exit(1);
  435.  
  436.     }
  437.  
  438.     printf("\nNOM:   ");
  439.  
  440.     leelin(&c.nom,9);
  441.  
  442.     printf("\nCOGNOM:   ");
  443.  
  444.     leelin(&c.cognom,29);
  445.  
  446.     printf("\nADRECA:   ");
  447.  
  448.     leelin(&c.adreca,29);
  449.  
  450.     printf("\nData de Neiximent: ");
  451.  
  452.     printf("\nDIA: ");
  453.  
  454.     scanf("%d",&c.dia);
  455.  
  456.     printf("\nMES: ");
  457.  
  458.     scanf("%d",&c.mes);
  459.  
  460.     printf("\nANY: ");
  461.  
  462.     scanf("%d",&c.any);
  463.  
  464.     c.next=-1; /* No apunta a cap registre,es l'ultim*/
  465.  
  466.     i=fhash(c.dia,c.mes,c.any); /*Calcula el hash*/
  467.  
  468.     hueco(pf,i,c); /* Modul que escriu al fitxer els nous registres */
  469.  
  470.     fclose(pf);
  471.  
  472.  
  473.  
  474. } /* Fi de escriu */
  475.  
  476.  
  477.  
  478. void leelin(char *linia,int lon){
  479.  
  480.  
  481.  
  482. /* Funcio que llegeix linies amb qualsevol caracter menys el LF,
  483.  
  484.    caracter 10 taula ASCII de 7 bits */
  485.  
  486.  
  487.  
  488. /* Permet llegir linies amb espais en blanc */
  489.  
  490.  
  491.  
  492.     int i; /* Caracter d'entrada com a sencers */
  493.  
  494.     int j; /* Comtador del nombre de caracters llegits */
  495.  
  496.  
  497.  
  498.     j=0;
  499.  
  500.  
  501.  
  502.     do{  /*Filtrat de LF o blancs inicials */
  503.  
  504.         i=getchar();
  505.  
  506.     }
  507.  
  508.     while((i==10) || (i==32));
  509.  
  510.  
  511.  
  512.        *(linia+j)=i; /* Assigna el 1er caracter llegit */
  513.  
  514.        j++; /* S'incrementa despres de llegir el 1er caracter */
  515.  
  516.  
  517.  
  518.        while((i!=10) && (j<=lon)){ /* Fins llegir el caracter LF o
  519.  
  520.                        superar la longitud del vector */
  521.  
  522.  
  523.  
  524.         i=getchar(); /* Pren caracters del tecla */
  525.  
  526.         if((i!=10) && (j <= lon))
  527.  
  528.             *(linia+j)=i; /* Assigna el caracters llegits */
  529.  
  530.         else
  531.  
  532.             *(linia+j)='\0'; /* Marca la fi de la cadena */
  533.  
  534.  
  535.  
  536.         j++; /* Incrementa el comptador de caracters llegits */
  537.  
  538.     }
  539.  
  540. }  /* fi de leelin */
  541.  
  542.  
  543. int ordenar(struct client *c1, struct client *c2){
  544.     return (strcmp(c1->nom, c2->nom));
  545. }

Cuando le doy a la opción de ordenar me da fallo de segmentación, ¿por qué?