2010-12-15 46 views
-2

Ce que mon programme ne .. lire un fichier texte formatHash Table: il n'enregistre pas correctement

store name 1 
itemcode quantity 
itemcode quantity 
. 
. 
store name 2 
itemcode quantity 
itemcode quantity 
. 
. 

Lorsque vous exécutez mon code vous demandera d'entrer une tâche. il y a trois options

L itemcode quantity 

entrant dans la séquence ci-dessus affichera tous les magasins qui contient cet élément avec la quantité donnée.

U itemcode quantity storename 

cette option prend trois arguments ItemCode quantité int et storename la fonction de cette option simplement mettre à jour le magasin étant donné la quantité de quantité. Cette option appelle ma méthode Savefile qui sauvegarde la structure de données actuelle dans le fichier.

Problème.

Il y a un problème auquel je suis confronté. chaque fois que je mets à jour le fichier, il met à jour avec succès mais quand Entrer commande Q pour arrêter de fumer et l'enregistrer n'enregistre pas correctement ..

save_file(char *) 

il a perdu des données entières que le premier magasin est économiser ..

stores.txt 

carrefour_Milan 
12345678 12 
23456766 16 
carrefour_Torino 
12345678 65 
67676765 12 
Carrefour_Vercelli 
23456766 20 

et aussi pouvez-vous me aider à trouver la complexité temporelle de

int listfile(char *) 

et

int updatefile(char *,int ,char *) 

Je veux dire Big O.

#include<stdio.h> 
    #include<string.h> 
    #include<stdlib.h> 
    #define MAX_ITEM 1000 
    #define MAXS 129 
    #define MAXL 132 
    #define MAXC 9 
    FILE *fp; 
    typedef struct store{ 
     char Storename[MAXS]; 
     int quantity; 
     struct store *NEXT; 
     }STORE; 

    typedef struct item{ 
     char item_code[MAXC]; 
     struct store *Stores; 
     struct item *NEXT; 
     }ITEM; 


    ITEM *list_item[MAX_ITEM]; 
    int readfile(char *fname); 
    int update_file(char *item_code,int qty,char *name); 
    int hash(char *item_code); 
    int save_file(char *fname); 
    void init(); 
void init(){ 
    int i; 
    for(i=0;i<MAX_ITEM;i++) 
     list_item[i]=NULL; 
    } 
int readfile(char *fname){ 
     char *p,line[MAXL+1],storen[MAXL+1]; 
     int pos; 
     ITEM *current=NULL,*prev=NULL; 
     STORE *s_cur=NULL,*s_prev=NULL; 
     char itemcode[MAXC];int qty; 
     if((fp=fopen(fname,"r"))==NULL) 
      return -1; 
     while(!feof(fp)){ 
      if(fgets(line,MAXL+1,fp)==NULL) 
       break; 
      if((p=strchr(line,'\n'))==NULL) 
       ; 
      else 
       *p='\0'; 
      if(line[0]>='a' && line[0]<='z' ||line[0]>='A' && line[0]<='Z') 
       strcpy(storen,line); 
      else{ 
       //fgets(line,MAXL,fp); 
       if(sscanf(line,"%s %d",itemcode,&qty)>0){ 

        current=(ITEM *)malloc(sizeof(ITEM)); 
        if(current==NULL) 
         return -1; 

        pos=hash(itemcode); 

        if(list_item[pos]==NULL){ 
         list_item[pos]=current; 
         if((s_cur=(STORE *)malloc(sizeof(STORE)))==NULL) 
          return -1; 

           strcpy(s_cur->Storename,storen); 
           strcpy(current->item_code,itemcode); 
           s_cur->quantity=qty; 
           current->Stores=s_cur; 
           s_cur->NEXT=NULL; 
           current->NEXT=NULL; 
        } 
        else{ 
         ITEM *q=list_item[pos]; 
         if((s_cur=(STORE *)malloc(sizeof(STORE)))==NULL) 
          return -1; 
         while(q!=NULL){ 
          if(strcmp(q->item_code,itemcode)==0){ 
           STORE *temp=q->Stores,*temp_a=NULL; 
           if(temp==NULL){ 
            q->Stores=s_cur; 
            strcpy(s_cur->Storename,storen); 
            s_cur->quantity=qty; 

            s_cur->NEXT=NULL; 
            } 
           else{ 
          while(temp!=NULL){ 
           temp_a=temp; 
           temp=temp->NEXT; 
          } 

           temp_a->NEXT=s_cur; 
           strcpy(s_cur->Storename,storen); 
           s_cur->quantity=qty; 
           s_cur->NEXT=NULL; 
           } 
          } 
         q=q->NEXT; 
         } 
         if(q==NULL){ 
          q=current; 
          current->NEXT=NULL; 
          current->Stores=s_cur; 
          strcpy(s_cur->Storename,storen); 
          s_cur->quantity=qty; 
          s_cur->NEXT=NULL; 
          } 
         } 
        } 
      } 
     } 
    fclose(fp); 
return 0; 
} 

int listfile(char *item_code,int qty){ 
      int i; 
      ITEM *u=NULL; 
      item_code[strlen(item_code)]='\0'; 
      if(list_item[hash(item_code)]==NULL) 
       return -1; 
      else{ 
       u=list_item[hash(item_code)]; 
       while(u!=NULL){ 
        if(strcmp(u->item_code,item_code)==0){ 
         STORE *temp=u->Stores; 
         while(temp!=NULL){ 
          if(temp->quantity>=qty){ 

          printf("STORE %s\n",temp->Storename); 
          } 
          temp=temp->NEXT; 
          } 
      } 
      u=u->NEXT; 
       } 
      } 
      return 0; 
    } 
    int update_file(char *item_code,int qty,char *name){ 

     ITEM *u=NULL; 
     item_code[strlen(item_code)]='\0'; 
     name[strlen(name)]='\0'; 
     if(list_item[hash(item_code)]==NULL) 
     return -1; 

     u=list_item[hash(item_code)]; 
     if(u==NULL) 
      return -1; 
     while(u!=NULL){ 
      if(strcmp(u->item_code,item_code)==0){ 
       STORE *temp=u->Stores; 
       while(temp!=NULL){ 
        if(strcmp(temp->Storename,name)==0) 
         temp->quantity+=qty; 
         temp=temp->NEXT; 
       } 
      } 
     u=u->NEXT; 
     } 
     return 0; 
    } 
    int hash(char *item_code){ 
     int sum=0,s=0; 
     while(item_code[s]!='\0'){ 
     sum+=33*item_code[s]; 
     s++;} 
     return sum%MAX_ITEM; 
     } 

    void clear(){ 
      char c; 
      while(c!='\n') 
       scanf("%c",&c); 
      } 

    main(){ 
     int y; 
     char fname[]="stores.txt",line[MAXL],command,z[MAXS]; 
     char x[MAXC]; 
     init(); 
     if(readfile(fname)==-1) 
      printf("Error reading file!"); 
     else{ 
     do{ 
      printf("Enter task:"); 
      fgets(line,MAXL,stdin); 
      sscanf(line,"%c",&command); 
      switch(command){ 
       case 'L': sscanf(line,"%c%s%d",&command,x,&y); 

          if(listfile(x,y)==-1) 
          printf("No items were found\n"); 
          break; 
       case 'U':sscanf(line,"%c%s%d%s",&command,x,&y,z); 
         if(update_file(x,y,z)==0) 
          printf("Update OK\n"); 
         else 
          printf("Error when updating\n"); 
          break; 
       case 'Q':if(save_file(fname)==0) 
          printf("Done\n!"); 
          break; 
       default:printf("Enter correct command\n"); 
         break; 
       } 
      }while(command!='Q'); 
     } 
    } 
int save_file(char *fname){ 
ITEM *p=NULL,*q=NULL; 
int num=0,i,j; 
char str[MAXS]; 

if((fp=fopen(fname,"w"))==NULL) 
    return -1; 
    for(i=0;i<MAX_ITEM;i++){ 
     if(list_item[i]==NULL) 
      ; 
     else{ 
      p=list_item[i]; 
      while(p!=NULL){ 
       STORE *s=p->Stores; 
       if(s==NULL) 
        ; 
       else{ 
        if(strcmp(s->Storename,"0000\0")!=0){ 
        strcpy(str,s->Storename); 
        // puts(str); 
        fprintf(fp,"%s\n",str); 
        } 
        while(s!=NULL){ 
        for(j=0;j<MAX_ITEM;j++){ 
         if(list_item[j]==NULL) 
          ; 
         else{ 
          q=list_item[j]; 
          while(q!=NULL){ 
           STORE *st=q->Stores; 
           if(st==NULL) 
            ; 
            else{ 
             while(st!=NULL){ 
             if(strcmp(st->Storename,str)==0 && strcmp(st->Storename,"0000\0")!=0){ 

              printf("%s %d\n",q->item_code,st->quantity); 
              fprintf(fp,"%s %d\n",q->item_code,st->quantity); 
              strcpy(st->Storename,"0000\0"); 
              } 
              st=st->NEXT; 
             } 
             } 
           q=q->NEXT; 
           } 
          } 
         } 
         s=s->NEXT; 
         } 
       } 
     p=p->NEXT; 
     } 
     } 
    } 
    fclose(fp); 
    return 0; 
     } 
+2

Veuillez formater votre code, et s'il vous plaît réduisez cela à un petit morceau de code qui démontre réellement votre problème. C'est beaucoup de code. – birryree

+1

Est-ce un problème de devoirs? Si oui, merci de le marquer comme tel. – George

+4

Mon conseil est d'abord commenter votre code de manière exhaustive, en vous parlant à travers chaque étape. –

Répondre

3

Ceci est un désordre incohérent et illisible. Je suggère que les premières étapes pour refactoriser la mise en page.

Réparer l'indentation afin qu'elle reflète la structure du code. Choisissez un style contreventement et utilisez-le régulièrement. Quelque chose comme ça

if(x){ 
    ; 
    }else{ 
     foo(); 
     } 

devrait mieux ressembler à ceci:

if (x) { 
    ; 
} 
else { 
    foo(); 
} 

C'est un bien meilleur point de départ pour tout le débogage et la maintenance. Et il y a beaucoup d'entretien nécessaire.

+0

J'ai effectivement coupé et collé une partie de votre code dans un éditeur de texte afin que je puisse le mettre en retrait correctement afin que je puisse le lire avec précision. Secure fait un très bon point, surtout si vous voulez que d'autres personnes prennent la peine de lire et de commenter votre code. – AlastairG

3

Votre code est très inefficace. Par exemple, lors de la lecture du fichier, vous déplacez la structure du magasin séparément dans les deux branches de l'instruction if et copiez le nom du magasin à trois endroits différents, toujours dans les différents chemins de code. Pourquoi ne pas simplement centrer la structure du magasin et l'initialiser correctement avant de déterminer où le mettre?

Toujours dans la fonction de lecture du fichier, si la position de la table de hachage correspondant à l'élément n'est pas vide, la mémoire allouée à "courant" est divulguée.

De plus, si vous trouvez en fait un match pour l'élément, vous ne cassez pas de la boucle qui signifie que le bloc de code commençant:

    if(q==NULL){ 
         q=current; 

est exécuté. Enfin, pour l'instant, si un emplacement dans la table de hachage est rempli mais qu'il n'y a pas de code article correspondant, l'élément ne sera pas placé dans la table de hachage. Regardez votre code. A quel point affectez-vous "current" à n'importe quelle partie de la chaîne qui commence à "list_item [pos]"? Vous ne le faites pas. Faire "q = current" stocke juste une valeur dans une autre variable.Ce dont vous avez besoin est quelque chose comme:

current->next = list_item[pos]; 
list_item[pos] = current; 

Pour l'ajouter au début de la liste.

Je vous suggère de corriger votre fonction de lecture de fichiers avant de vous soucier de la fonction d'écriture de fichier.

P.s. un upvote et une demande de plus de commentaires peuvent vous aider un peu plus. En fonction de mon niveau d'activité et du fait que d'autres personnes peuvent aussi être dérangées pour m'aider.