哈希表:它无法正确保存

时间:2010-12-15 03:44:48

标签: c

我的程序做什么.. 阅读格式为

的文本文件
store name 1
itemcode  quantity
itemcode  quantity
.
.
store name 2
itemcode  quantity
itemcode  quantity
.
.

当您运行我的代码时,您将要求输入任务。 有三个选项

L itemcode quantity

输入上述序列将打印包含给定数量的该项目的所有商店。

U itemcode quantity storename

此选项采用三个参数itemcode int quantity和storename 此选项的功能只是使用金额更新给定商店。

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 *)

我的意思是大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 个答案:

答案 0 :(得分: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和一个更多评论的请求可能会给你一些帮助。取决于我的忙碌程度以及其他人是否也可以帮忙。

答案 1 :(得分:3)

这是一个不一致且难以理解的混乱。我建议作为重构布局的第一步。

修复缩进,使其反映代码结构。选择支撑式并始终如一地使用它。像这样的东西

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

最好看起来像这样:

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

这是任何调试和维护的更好的起点。并且需要进行大量维护。