我的程序做什么.. 阅读格式为
的文本文件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;
}
答案 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();
}
这是任何调试和维护的更好的起点。并且需要进行大量维护。