Jurgen Cuschieri Jurgen Cuschieri - 2 months ago 17
C Question

infinite loop in while loop

fp=fopen("Product.dat","rb+");
while (fread(&prod,sizeof (prod),1,fp)==1) {
prod.stockquant = prod.stockquant + prod.stockorderquant;
prod.stockorderquant = 0;
fseek(fp, -sizeof(prod), SEEK_CUR);
fwrite (&prod, sizeof(prod), 1, fp);
}
fclose (fp);


Once I get into the while loop, I am getting an infinite loop.
The file pointer is fp, the prod is an instance of Struct called PRODUCT, stockquant and stockorderquant ara variables in the struct. I am attempting to change the values of stockquant and stockorderquant. This is a batch update tht im doing for my project. I am trying to go through the whole file called product.dat while editing each product's stockquant and orderquant.

Why am I getting an infinite loop?
This method seems to work when I use it in an if statement that checks if the prod.id = userinput or not.

Any help?

Some extra code:

void batchupdate(void) {
system("cls");
FILE *fp;
int c=0;
gotoxy(20,4);
printf("****Batch Update Section****");
char another='y';
while(another=='y')
{
system("cls");
gotoxy(15,6);
printf("Are you sure you want to Batch update (Press Y or N)?");

if((getch()=='y') || (getch() == 'Y')) {
system("cls");
int pos;

fp=fopen("Product.dat","rb+");
while(fread(&prod,sizeof(prod),1,fp)==1) {
prod.stockquant = prod.stockquant + prod.stockorderquant;
product.stockorderquant = 0;

fseek(fp, -(sizeof(prod)), SEEK_CUR);
fwrite (&prod, sizeof(prod), 1, fp);
getchar();
pos = ftell(fp);
printf("%d",&pos);


}
fclose (fp);

gotoxy(15,16);
printf("Complete");
gotoxy(15,18);
printf("All products stock quantity have been updated. The stock order quantity has been reset");

gotoxy(15,16);
printf("Do you want to modify another product?(Y/N)");
fflush(stdin);
another=getch() ; }

else { if((getch()=='n') || (getch() == 'N')) {
mainmenu();
}
}
}
returnfunction();
}


This is how I list my products (and it works!) (Please not the order quantity displayed here has nothing to do with the stockorderquant

void listproduct(void)
{
int x;
FILE *fp;
system("cls");
gotoxy(1,1);
printf("*********************************Product List*****************************");
gotoxy(2,2);
printf("Name ID Price StockQuant Order Quant Description");
x=4;
fp=fopen("Product.dat","rb");
while(fread(&prod,sizeof(prod),1,fp)==1){
gotoxy(2,x);
printf("%s",prod.prodname);
gotoxy(20,x);
printf("%d",prod.prodid);
gotoxy(26,x);
printf("%.2f",prod.price);
gotoxy(34,x);
printf("%d",prod.stockquant);
gotoxy(46,x);
printf("%d",prod.orderquantity);
gotoxy(59,x);
printf("%s",prod.description);
printf("\n\n");
x++;
}
fclose(fp);
gotoxy(35,25);
returnfunction();
}


my struct is defined like below:

struct PRODUCT
{
int id;
char name[30];
char desc[50];
float price;
int stockquant;
int orderquant;
int stockorderquant;
};

struct PRODUCT prod;

Answer

Let me quote the man page for fopen:

Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes necessary under Linux) to put an fseek(3) or fgetpos(3) operation between write and read operations on such a stream. This operation may be an apparent no-op (as in
fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect.

Calling fseek after the write,

fseek(fp, -sizeof(prod), SEEK_CUR);
fwrite (&prod, sizeof(prod), 1, fp);
fseek(fp, 0, SEEK_CUR);

ought to fix it.

Comments