C program to add 2 polynomials and then displaying it - c

I am writing a C program to add 2 polynomials given by user then displaying it in a separate function but it is not adding anything. In fact, it is not giving any type of error message so I am very confused. I think the mistake can be in 'addpoly' function or display function. I don't know what I am doing wrong. Any type of help will be appreciated.
#include<stdio.h>
#include<stdlib.h>
#define MAX 3
struct polynomial
{
int coeff;
int exp;
struct polynomial *next;
};
typedef struct polynomial polynomial;
polynomial *p1=NULL,*p2=NULL,*p3=NULL, *head_address=NULL;
polynomial* create()
{
polynomial *head_address=NULL, *prev_address=NULL, *new_address=NULL;
int i;
for(i=0;i<MAX;i++)
{
new_address=(polynomial*)malloc(sizeof(polynomial));
printf("Enter coeff:\n");
scanf("%d",&new_address->coeff);
printf("Enter exp:\n");
scanf("%d",&new_address->exp );
new_address->next=0;
if(head_address==NULL){
head_address=prev_address=new_address;
}
else{
prev_address->next=new_address;
prev_address=new_address;
}}
return head_address; }
void polyadd(polynomial *p1, polynomial *p2,polynomial *p3)
{
//polynomial* p3=NULL;
while(p1->next!=NULL && p2->next!=NULL){
if(p1->exp > p2->exp){
p3->coeff=p1->coeff;
p3->exp=p1->exp;
p1=p1->next;
}
else if(p1->exp < p2->exp){
p3->coeff=p2->coeff;
p3->exp=p2->exp;
p2=p2->next;
}
else if(p1->exp==p2->exp){
p3->coeff=p1->coeff + p2->coeff;
p3->exp=p1->exp;
p1=p1->next;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL; }
while(p1->next || p2->next){
if(p1->next){
p3->exp=p1->exp;
p3->coeff=p1->coeff;
p1=p1->next;
}
else if(p2->next){
p3->exp=p2->exp;
p3->coeff=p2->coeff;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL;
}
}
void display(polynomial *temp){
polynomial *p3;
p3=temp;
temp=head_address;
while(temp->next!=NULL)
printf("%dx^%d",temp->coeff,temp->exp);
temp=temp->next;
if(temp->next!=NULL){
printf(" + ");
}
}
int main(){
polynomial *p1,*p2,*p3;
p1=create();
printf("Next:\n");
p2=create();
polyadd(p1,p2,p3);
printf("Result:\n");
display(p3);
return 0;
}

Your issue looks like a memory reference error. In your polyadd() function you're not mallocing as much as you need to. Your base p3 pointer for your linked list is still unallocated when you start referencing off it in your first while loop. To fix your memory issue you'll want to malloc p3 before using it and then make sure the subsequent ->next instances all get malloced before being used.
I don't think this is causing you issues currently but you also have global variables defined at the top and then defined again in main(). The local variables will be the only ones used as long as they're present but I would delete your globals and make sure you don't have unused duplicates to avoid confusion.

Related

Issue with C, program prints values that aren't supposed to print

I've been trying to find an issue with this code for a few days but I still can't find it. The main problem here is that, when printing the values of each node, it tries to print an extra node and makes up new values.
The code works the following way, for example: I put numbers 10,11,15 and if the sum of all three numbers of the node is more than 20 then it adds the double before so the result would be: 20,22,30 || 10,11,15.
Every time I try to execute this code in Visual Studio Code the program prints:
20,22,30 || 10,11,15 || 0,26345856,301989906. As you can see, the program tries to print another node that doesn't exist so it makes up values. I've tried on some online compilers and this isn't a problem, so what I would like to know is if there is any error in my code or if it's the compiler.
#include <stdio.h>
#include <stdlib.h>
typedef struct list{
int num;
int num1;
int num3;
struct list *next;
}node;
void create (node *p){
printf("Input first number: ");
scanf("%d",&p->num);
if (p->num==0)
p->next=NULL;
else{
printf("Input second number: ");
scanf("%d",&p->num1);
printf("Input third number: ");
scanf("%d",&p->num3);
p->next=(node*)malloc(sizeof(node));
create (p->next);
}
}
void show (node *p){
if (p->next !=NULL){
printf ("\n%d",p->num);
printf ("\n%d",p->num1);
printf ("\n%d",p->num3);
show (p->next);
}
}
node* add(node *p){
node *aux;
if((p->num+p->num1+p->num3)>20){
aux=(node *)malloc(sizeof(node));
aux->num=p->num*2;
aux->num1=p->num1*2;
aux->num3=p->num3*2;
aux->next=p;
p=aux;
}
return p;
}
void add2 (node *p){
node *aux=NULL;
while(p->next!=NULL){
if((p->next->num +p->next->num1+ p->next->num3)>20){
aux=(node *)malloc(sizeof(node));
aux->num=p->next->num*2;
aux->num1=p->next->num1*2;
aux->num3=p->next->num3*2;
aux->next=p->next;
p->next=aux;
p=p->next;
}
p=p->next;
}
}
int main(){
node *prin=NULL;
prin=(node*)malloc(sizeof(node));
create(prin);
printf("Input numbers were: ");
show (prin);
prin=add(prin);
add2(prin->next);
printf("\nList with added nodes: ");
show(prin);
}
You are always creating a 'dummy' node at the foot of your list. For example, if you enter 0 as the very first input, you will have a single-entry list where only the num (set to that 0) and next (set to NULL) members are initialized. The num1 and num3 fields are left uninitialized by the create function. Likewise if, as in your given test case, you enter (and initialize) actual values for those last two fields, you will still have created a new 'foot' node in the next call to create.
As it happens, on your system, these uninitialized data fields have 'random' values that, together, add up to more than 20. (This is perfectly allowable by the C standard, but some compilers and/or platforms will, by default, set that uninitialized data to zero.)
Thus, in your call to the add function, the if test condition in:
if ((p->num + p->num1 + p->num3) > 20) {
//...
will evaluate to TRUE and a new node will be added, with num1 and num3 having values twice that of the original 'random' values.
To fix the problem, set the num1 and num3 fields to zero (or some other small/negative numbers) in your create function, when the 'sentinel zero' end-of-input mark is entered for the num field:
void create(node* p)
{
printf("Input first number: ");
scanf("%d", &p->num);
if (p->num == 0) {
p->next = NULL;
p->num1 = 0; // You MUST ensure that the sum of these two numbers
p->num3 = 0; // is LESS THAN 20 ... or a new node will be created
}
else {
printf("Input second number: ");
scanf("%d", &p->num1);
printf("Input third number: ");
scanf("%d", &p->num3);
p->next = (node*)malloc(sizeof(node));
create(p->next);
}
}
EDIT: To see how this 'bug' is happening, try just setting the num1 field to a specific number (say, 42) and leaving num3 uninitialized. Then, only one of the 'made up' values will be unexplained - the other one will be twice what you have specified (so, 84). This would make a good exercise, IMHO.

C function that creates a linked list with "divisible by 3" numbers from another linked list

First, I need to create and show a list that ends with number 1000. That works well.
Then, I want to create another list with only the numbers that are divisible by 3 in the first list, but it doesn't work.
The worst thing is that it doesn't even tell me what's going on. It just gives error in the execution but the console doesn't say anything.
I will really appreciate any help.
I tried all.
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define CANTIDAD_NUMEROS 13
#define CANTIDAD_NUMEROS2 6
#define DESDE 1
#define HASTA 10
typedef struct lista{
int num;
struct lista *sig;
}nodo;
void crear (nodo *pt, int, int);
void crear2 (nodo *pt, int, nodo *pt2);
void mostrar(nodo *pt);
int main()
{
int i=0;
int t=0;
nodo *prin;
nodo *prin2;
prin=(nodo*)malloc(sizeof(nodo));
prin2=(nodo*)malloc(sizeof(nodo));
crear(prin,i, t); //creates first list
mostrar (prin); //shows first list
crear2(prin,i, prin2); //gets 'divisible by 3' numbers
mostrar(prin2); // shows second list
return 0;
}
//creates list
void crear (nodo *registro, int cont, int t)
{
scanf("%d", &t);
registro->num = t;
if (registro->num == 1000)
registro->sig=NULL;
else
{
registro->sig=(nodo*)malloc(sizeof(nodo));
cont++;
crear (registro->sig,cont, t);
}
return;
}
//shows list
void mostrar (nodo *registro)
{
if (registro->sig !=NULL)
{
printf ("%d\n",registro->num);
mostrar (registro->sig);
}else{
printf("%d\n",registro->num);
}
return;
}
//creates second list with only numbers that are divisible by 3
void crear2 (nodo *registro, int cont, nodo *registroNuevo)
{
if ((registro->num % 3) == 0){
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
}
if(registro->sig != NULL){
crear2(registro->sig,cont, registroNuevo->sig);
}else{
return;
}
}
I expect to have the 1st list shown (which it's happening) and also the 2nd list shown with the numbers that are divisible by 3, which doesn't happen.
First of all, I admire your dedication to recursion!
The problem is that in crear2, registroNuevo->sig is uninitialized which causes a segfault. I almost always start a function that operates on a recursive linked data structure by checking if the parameter node is null. If so, I can safely continue on with the body of the function. Following this logic of protecting against nulls, we need to pass the registroNuevo node along without touching it in the case when registro->num % 3 != 0 and ensure all of its fields are initialized.
Here's the corrected function:
void crear2(nodo *registro, int cont, nodo *registroNuevo)
{
if (registro) {
if (registro->num % 3 == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = NULL;
if (registro->sig) {
registroNuevo->sig = malloc(sizeof(nodo));
}
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
crear2(registro->sig, cont, registroNuevo);
}
}
}
Having said that, this function is still a bit less than ideal for a couple reasons. First of all, the name is vague and could describe the behavior better. Also, if there are no items divisible by three, you've got a malloced node back in the calling scope that never gets initialized, so it's a bit brittle in that regard. Thirdly, even with a parameter, it feels like a highly specific function without much reusability factor that could be written iteratively inside the calling scope like:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo
{
int num;
struct nodo *sig;
} nodo;
nodo *crear(nodo *registro, int num)
{
nodo *n = malloc(sizeof(nodo));
n->num = num;
n->sig = registro;
return n;
}
void mostrar(nodo *registro)
{
if (registro)
{
printf("%d->", registro->num);
mostrar(registro->sig);
}
else puts("");
}
void free_lista(nodo *registro)
{
if (registro)
{
free_lista(registro->sig);
free(registro);
}
}
int main()
{
nodo *prin = NULL;
nodo *prin_div_3 = NULL;
for (int t; scanf("%d", &t) && t != 1000;)
{
prin = crear(prin, t);
}
nodo *tmp = prin;
while (tmp)
{
if (tmp->num % 3 == 0)
{
prin_div_3 = crear(prin_div_3, tmp->num);
}
tmp = tmp->sig;
}
mostrar(prin);
mostrar(prin_div_3);
free_lista(prin);
free_lista(prin_div_3);
return 0;
}
This isn't perfect--without tail nodes, adding to the list is a bit less than ideal, but dangling heads are eliminated, and hopefully it shows an alternate approach to organizing program logic and functions.
A few other remarks:
Always free memory that you've allocated. You can write a simple recursive routine to do so, like free_lista as shown in the above example.
Consider avoiding highly specific functions with hard-coded values like 3 and 1000. Make these parameters to maximize reusability.
crear2 never uses the cont member, and you have global constants that are unused. It's a good idea to clean these up to help clarify your debugging efforts and reduce visual clutter.
No need to cast the result of malloc.
if (registro->sig !=NULL) as the first line of a function is going to crash on a null. You don't need != NULL either. if (registro) { ... } is clearest and avoids problems with null parameters.
void crear2 (nodo *registro, int cont, nodo *registroNuevo) {
if ((registro->num % 3) == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo);
}
}
This is my approach, but you are still getting a final unexpected 0 at the last mostrar() call; and you still need to do the 'free' calls. I think you should avoid the recursive calls, there are easier ways to do it. Saludos.

Inserting at the end of queue in C

I am trying to insert node at the end of queue and facing below error . This is simple fundamental error while compiling the code but making my life hard.
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
new->str=s;
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}
Error :stack_queue.c:27:10: error: assignment to expression with array type
new->str=s;
Update : Using strncpy reolved the error , but code is not working as expected and stopping unexpectedly.
You can't assign to a static array like that. Consider using strcpy or strncpy to copy the contents of the character string instead.
You cannot assign a string to an array! An array have its own memory, you can write or read elements in the array, but cannot assign an address.
You can eventually copy the string s contents to the array:
strncpy(new->str, s, 19);
new->str[19] = '\0'; //Close the string in case of overflow.
We used strncpy to limit the copied characters to the array size (19 chars + the ending '\0').
You can try it. Only replace in new->str=s; to strcpy(new->str, s); (ie. s will be copy in to new->str)
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
strcpy(new->str, s);
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}
As already stated you will have to use strcpy (or strncpy) in order to assign the string.
Asides from that I wanted to mention two things:
Do not forget to free your memory allocated by malloc. Create a method to free a single node (examp) then you can also provide a method to destroy the whole list.
I would suggest to rename the variable new to avoid confusion (pure C compiler may deal with it, but C/C++ compiler will most likely get into trouble).
Considering your update:
Take a look at the following line
while(slide->next!=NULL)
At this time slide does not even exist (it is NULL), still you perform an operation on the pointer. This is the reason why the program crashes.
Your error is in the first call insert_last("hello "):
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
when you call it first time, head is NULL, so slide becomes NULL, but you don't check it, and call it in
while(slide->next!=NULL)
Here slide is null for the frst function call

Linked list sort from smallest to biggest

I am trying sort a number in a linked list from small to big.
But its not working !
the debugger says there are a problem when i put the second number into the
list ( in main )but i dont know why .
Any help ?
#include<stdio.h>
#include<stdlib.h>
typedef struct list list;
struct list{
int a;
list *nxt;
};
void sort(list *l){
int temp,tp;
list *AIDE,*k;
k=AIDE=(list*)malloc(sizeof(list));
while (l->nxt!= NULL)
{
while (l->nxt->a < l->a)
{
temp=l->a;
l=l->nxt;
l->nxt->a=temp;
l=l->nxt;
while (l->a < AIDE->nxt->a )
{
tp=AIDE->a;
AIDE->a=l->a;
AIDE->nxt->a=tp;
AIDE=AIDE->nxt;
}
}
l=l->nxt;
}
while (k->nxt!= NULL)
{
l->a=k->a;
l=l->nxt;
k=k->nxt;
}
l->nxt=NULL;
}
int main() {
list *t,*s;
int n,i,c=0;
printf("\n how many number you need to enter? ");
scanf("%d",&n);
s=t=(list*)malloc(sizeof(list)*n);
while (c!=n)
{
printf("\n Donner le nb %d :",c+1);
scanf("%d",&t->a);
t=t->nxt;
c++;
}
t->nxt=NULL;
sort(s);
while (t->nxt!=NULL)
{
printf("%d",t->a);
}
return 0;
}
In the loop where you have the problem, what do you think the expression t=t->nxt would do?
When you enter the loop, t is pointing to allocated but uninitialized memory, therefore dereferencing e.g. t->nxt will lead to undefined behavior.
A simple solution would be to e.g. do
t->nxt = t++ + 1;

Hash Table: it doesn't save correctly [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
What my program do..
read a text file of format
store name 1
itemcode quantity
itemcode quantity
.
.
store name 2
itemcode quantity
itemcode quantity
.
.
When you Run my code you will Ask to Enter a task.
there are three options
L itemcode quantity
entering the above sequence will print all the stores which contains that item with the given quantity.
U itemcode quantity storename
this option takes three arguments itemcode int quantity and storename
the Function for this option just update the given store with the amount quantity.
Q
this option call my Savefile method which save the current data structure back to the file.
Problem.
There is a problem I am facing.
whenever I update file it updates successfully but when Enter Command Q to quit and save it doesn't save correctly..
save_file(char *)
it lost whole data just the first store is save..
stores.txt
carrefour_Milan
12345678 12
23456766 16
carrefour_Torino
12345678 65
67676765 12
Carrefour_Vercelli
23456766 20
and also can you help me in finding the time complexity of
int listfile(char *)
and
int updatefile(char *,int ,char *)
I mean 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;
}
This is an inconsistent and unreadable mess. I suggest as first steps to refactor the layout.
Repair the indentation so it reflects the code structure. Chose a bracing style and use it consistently. Something like this
if(x){
;
}else{
foo();
}
should better look like this:
if (x) {
;
}
else {
foo();
}
That's a much better starting point for any debugging and maintenance. And there is a lot of maintenance necessary.
Your code is very inefficient. For example when reading the file, you malloc the store structure separately in both branches of the if statement, and copy the store name in three different places, again in all different code paths. Why not simply malloc the store structure and initialise it correctly before you work out where to put it?
Also in the read file function, if the hash table position corresponding to the item is not empty, the memory allocated to "current" gets leaked.
Furthermore, if you actually find a match for the item, you don't break out of the loop which means that the block of code beginning:
if(q==NULL){
q=current;
gets executed.
Lastly (for now), if a slot in the hash table is filled but there is no matching itemcode then the item won't get put into the hash table. Look at your code. At what point do you assign "current" to any part of the chain that starts at "list_item[pos]"? You don't. Doing "q = current" just stores one value in another variable. What you need is something like:
current->next = list_item[pos];
list_item[pos] = current;
To add it on at the beginning of the list.
I suggest you fix your file reading function before worrying about your file writing function.
P.s. an upvote and a request for more comments may get you some more help. Depending on how busy I am and whether others can also be bothered to help.

Resources