2010-12-15 7 views
-2

내 프로그램이 할 무엇 ... 는 해시 테이블 :이 저장되지 않습니다 제대로

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

당신이 내 코드를 실행할 때 작업을 입력 할 수 요청합니다 형식

의 텍스트 파일을 읽습니다. 지정된 수량과 그 항목에 포함 된 모든 점포를 인쇄 될 상기 입력 시퀀스를 세 가지 옵션

L itemcode quantity 

있다.

U itemcode quantity storename 

이 옵션은 세 개의 인수 그냥 양의 수량 주어진 저장소를 업데이트이 옵션 INT 수량 및 StoreName이 기능을 itemcode합니다.

Q 

이 옵션은 현재 데이터 구조를 다시 파일에 저장하는 Savefile 메서드를 호출합니다.

문제.

내가 직면하는 문제가 있습니다. 나는 그것이 성공적으로 업데이트 파일을 업데이트 할 수 있지만 입력 할 때 명령 Q는 .. 단지 첫 번째 저장소 저장입니다

save_file(char *) 

그것이 전체 손실 된 데이터를 .. 종료가 제대로 저장하지 않습니다 저장할 때마다

stores.txt 

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

또한 당신은

int listfile(char *) 

의 시간 복잡도를 찾는 나를 도울 수
int updatefile(char *,int ,char *) 

(3210) 나는 큰 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

코드를 형식화하고이 코드를 실제로 문제를 나타내는 작은 코드 조각으로 줄이십시오. 그것은 많은 코드입니다. – birryree

+1

숙제에 문제가 있습니까? 그렇다면 태그를 붙이십시오. – George

+4

제 조언은 코드를 철저히 설명하고 각 단계를 통해 스스로 이야기하는 것입니다. –

답변

3

이것은 일관성이없고 읽을 수없는 혼란입니다. 레이아웃을 리팩토링하는 첫 단계로 제안합니다.

들여 쓰기를 수정하여 코드 구조를 반영하십시오. 브레이싱 스타일을 선택하고 일관되게 사용하십시오. 이

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

같은 뭔가 더 나은 다음과 같아야합니다 디버깅 및 유지 보수에 대한 더 나은 출발점

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

합니다. 그리고 많은 정비가 필요합니다.

+0

실제로 텍스트의 일부를 잘라내어 텍스트 편집기에 붙여 넣었으므로 정확하게 들여 쓰기 할 수있어서 정확하게 읽을 수있었습니다. 보안은 특히 다른 사람들이 실제로 코드를 읽고 귀찮게하고 싶다면 매우 좋은 지적입니다. – AlastairG

3

귀하의 코드는 매우 비효율적이다 의미한다. 예를 들어 파일을 읽을 때 if 문 양쪽 분기에서 저장소 구조를 개별적으로 malloc하고 다른 모든 코드 경로에서 다시 세 위치에 저장소 이름을 복사합니다. 왜 상점 구조를 malloc하고 그것을 어디에 넣을 지 결정하기 전에 올바르게 초기화하지 않는 것이 좋을까요?

또한 읽기 파일 기능에서 해당 항목에 해당하는 해시 테이블 위치가 비어 있지 않으면 "현재"에 할당 된 메모리가 유출됩니다. 실제로 항목에 대한 일치를 찾을 경우

또한, 당신은 코드 블록이 시작하는 것을 의미 루프의 탈옥하지 않습니다

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

이 실행됩니다.

마지막으로 (현재) 해시 테이블의 슬롯이 채워졌지만 일치하는 항목 코드가없는 경우 해당 항목은 해시 테이블에 저장되지 않습니다. 당신의 코드를보십시오. "list_item [pos]"에서 시작하는 체인의 어느 부분에 "현재"를 할당합니까? 너는하지 않는다. "q = current"를 실행하면 하나의 값을 다른 변수에 저장합니다.필요한 것은 다음과 같습니다.

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

목록의 처음에 추가 할 수 있습니다.

파일 쓰기 기능을 걱정하기 전에 파일 읽기 기능을 수정하는 것이 좋습니다.

p.s. upvote 및 더 많은 의견을 요청하면 더 많은 도움을 얻을 수 있습니다. 내가 얼마나 바쁘고 다른 사람들도 도움을받을 수 있는지 여부에 따라.

관련 문제