2010-12-15 8 views
-2

Was mein Programm zu tun .. lesen Sie eine Textdatei im FormatHash Table: es wird nicht richtig speichern

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

Wenn Sie meinen Code ausführen Sie fragen wird, eine Aufgabe eingeben. gibt es drei Möglichkeiten

L itemcode quantity 

die obige Reihenfolge der Eingabe werden alle Geschäfte drucken, die das Element mit der angegebenen Menge enthält.

U itemcode quantity storename 

diese Option hat drei Argumente int Menge und Storenamen die Funktion für diese Option ItemCode nur den angegebenen Speicher mit der Menge Menge aktualisieren.

Diese Option ruft meine Savefile-Methode auf, die die aktuelle Datenstruktur in die Datei zurückspeichert.

Problem.

Es gibt ein Problem, mit dem ich konfrontiert bin. wenn ich Datei aktualisieren aktualisiert sie erfolgreich, aber wenn Befehl Q eingeben beenden und speichern Sie es nicht richtig speichern ..

save_file(char *) 

it ..

speichern gesamten Daten nur der erste Speicher ist verloren
stores.txt 

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

und auch können Sie mir helfen, die Komplexität von

int listfile(char *) 

und

bei der Suche nach
int updatefile(char *,int ,char *) 

ich meine 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

Bitte formatieren Sie Ihren Code, und reduzieren Sie dies bitte auf ein kleines Stück Code, das Ihr Problem tatsächlich zeigt. Das ist eine Menge Code. – birryree

+1

Ist das ein Hausaufgabenproblem? Wenn ja, bitte als solches markieren. – George

+4

Mein Rat ist, zuerst Ihren Code erschöpfend zu kommentieren und jeden Schritt selbst zu sprechen. –

Antwort

3

Dies ist ein inkonsistentes und unlesbares Durcheinander. Ich schlage als erste Schritte vor, das Layout zu überarbeiten.

Reparieren Sie die Einrückung so, dass sie die Codestruktur widerspiegelt. Wählen Sie einen stützenden Stil und verwenden Sie ihn konsequent. So etwas wie dies

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

sollte besser aussehen:

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

Das ist ein viel besserer Ausgangspunkt für jede Fehlersuche und Wartung. Und es ist viel Wartung notwendig.

+0

Ich habe tatsächlich etwas von Ihrem Code in einen Texteditor geschnitten und eingefügt, damit ich ihn richtig einrücken konnte, damit ich ihn genau lesen konnte. Sicher ist ein sehr guter Punkt, besonders wenn Sie möchten, dass andere Personen Ihren Code wirklich lesen und kommentieren. – AlastairG

3

Ihr Code sehr ineffizient ist. Wenn Sie beispielsweise die Datei lesen, mallokieren Sie die Geschäftsstruktur separat in beiden Zweigen der if-Anweisung und kopieren den Geschäftsnamen an drei verschiedenen Stellen erneut in alle unterschiedlichen Codepfade. Warum nicht einfach die Filialstruktur malloc und sie richtig initialisieren, bevor Sie herausfinden, wo Sie es ablegen sollen?

Wenn die Position der Hash-Tabelle, die dem Element entspricht, nicht leer ist, wird auch in der Lesedatei-Funktion der Speicher gelöscht, der "aktuell" zugeordnet ist.

Außerdem, wenn Sie tatsächlich eine Übereinstimmung für die Artikel finden, Sie brechen nicht der Schleife aus, was bedeutet, dass der Code-Block beginnen:

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

ausgeführt wird.

Zuletzt (für jetzt), wenn ein Slot in der Hash-Tabelle gefüllt ist, aber es keinen übereinstimmenden Itemcode gibt, wird das Item nicht in die Hash-Tabelle übernommen. Schau dir deinen Code an. An welchem ​​Punkt weisen Sie "current" jedem Teil der Kette zu, der bei "list_item [pos]" beginnt? Du nicht. Mit "q = current" wird nur ein Wert in einer anderen Variablen gespeichert.Was Sie brauchen, ist etwas wie:

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

Um es am Anfang der Liste hinzuzufügen.

Ich schlage vor, Sie reparieren Ihre Datei lesen Funktion, bevor Sie sich Sorgen über Ihre Datei schreiben Funktion.

Ps.s. Ein Upvote und eine Anfrage für weitere Kommentare können Ihnen helfen. Je nachdem, wie beschäftigt ich bin und ob andere sich auch darum kümmern können.