Thread: Binary file - delete record issue

  1. #1
    Registered User
    Join Date
    Jun 2012
    Posts
    127

    Binary file - delete record issue

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    
    typedef struct{
    	char code[6];
    	int year;
    	char country[26];
    } product;
    
    
    void add();
    void display();
    void del(int year);
    
    
    void add()
    {
    	FILE *addPtr;
    	product p;
    	char anymore = 'Y';
    
    
    	addPtr = fopen("product.dat","ab");
    
    
    	while(toupper(anymore) == 'Y')
    	{
    		printf("Product Code: ");
    		gets(p.code);
    		
    		printf("Expired year of the product: ");
    		scanf("%d",&p.year);
    
    
    		printf("Product country: ");
    		fflush(stdin);
    		gets(p.country);
    
    
    		fwrite(&p,sizeof(product),1, addPtr);
    
    
    		printf("Anymore:(Y/N) ?\t");
    		scanf("%c",&anymore);
    		fflush(stdin);
    	}
    	fclose(addPtr);
    	system("pause");
    	system("cls");
    }
    
    
    void display()
    {
    	FILE *disPtr;
    	product p;
    
    
    	disPtr = fopen("product.dat","rb");
    
    
    	/*
    	fread(&p,sizeof(product),1, disPtr);
    
    
    	while (!feof(disPtr));
    	{
    		printf("Product Code: %s\n",p.code);
    		
    		printf("Expired year of the product: %d\n",p.year);
    
    
    		printf("Product country: %s\n\n",p.country);
    		fread(&p,sizeof(product),1, disPtr);
    	}
    	*/
    
    
    	while ( (fread(&p,sizeof(product),1, disPtr)) == 1)
    	{
    		printf("Product Code: %s\n",p.code);
    		
    		printf("Expired year of the product: %d\n",p.year);
    
    
    		printf("Product country: %s\n\n",p.country);
    	}
    	
    	fclose(disPtr);
    	system("pause");
    	system("cls");
    
    
    }
    
    
    void del(int year)
    {
    	FILE *delPtr;
    	FILE *tempPtr;
    
    
    	product p;
    
    
    	delPtr = fopen("product.dat","rb");
    	tempPtr = fopen("temp.dat","wb");
    
    
    	while(fread(&p,sizeof(product),1,delPtr) == 1)
    	{
    		if (year == p.year)
    			fread(&p,sizeof(product),1,delPtr);
    
    
    		fwrite(&p,sizeof(product),1,tempPtr);
    	}
    
    
    	fclose(delPtr);
    	fclose(tempPtr);
    
    
    	system("cls");
    }
    
    
    int main()
    {
    	int menu, year;
    
    
    	do
    	{
    		printf("Product Processing System\n");
    		printf("=========================\n");
    
    
    		printf("1. Add product\n");
    		printf("2. Display product\n");
    		printf("3. Delete product\n");
    		printf("0. Exit\n");
    
    
    		printf("Your choice: ");
    		scanf("%d", &menu);
    		fflush(stdin);
    
    
    		system("cls");
    
    
    		switch (menu)
    		{
    			case 1:
    				add();
    				break;
    
    
    			case 2:
    				display();
    				break;
    
    
    			case 3:
    				printf("Year: ");
    				scanf("%d",&year);
    				del(year);
    				break;
    		}
    
    
    	}while (menu != 0);
    
    
    }
    Issue: After input year, it cannot delete the record if it is last record in del function.

    How to fix this issue?

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    $ make foo
    gcc -Wall -Wunreachable-code -g -std=c99 -pedantic  -lm -lpthread  foo.c   -o foo
    /tmp/ccykokEv.o: In function `add':
    /home/tyco/sandbox/cprogramming/foo.c:31: warning: the `gets' function is dangerous and should not be used.
    The gets function is so dangerous (prone to buffer overflow attacks), that the compiler doesn't even want you to use it. Try fgets instead. Just remember to strip off the trailing new line character.
    Code:
    fflush(stdin);
    That results in undefined behavior. Read this link and this link.

    I didn't do a full audit of your code, so you may have other problems as well.

    It would help us if you told us exactly what input you gave, like what records you inserted and what record year you tried to remove, to help us debug your issue.
    Code:
    while(fread(&p,sizeof(product),1,delPtr) == 1)
    {
        if (year == p.year)
            fread(&p,sizeof(product),1,delPtr);
     
        fwrite(&p,sizeof(product),1,tempPtr);
    }
    Your logic is a little bit off there. Basically, if the current record has a matching year, you read one more record. This has a few problems. What if you want to delete year 1998, and there are two such records in a row? You only delete one of them, and write the next one to temp.dat. Also, if you read the last record in the while line, and the year matches, you call fread again, which fails because it's at the end of the file, so the information in p is not updated, then you call fwrite regardless, writing the last record to temp.dat.

    Instead, only write the record if the year doesn't match that which you want to delete:
    Code:
    while (fread(...) == 1)
    {
        if (year != p.year)
            fwrite(...);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Update Record & Delete Record in File.
    By unsafe_pilot1 in forum C Programming
    Replies: 13
    Last Post: 05-18-2008, 07:22 AM
  2. The best way to delete a record from a file?
    By salvadoravi in forum C Programming
    Replies: 25
    Last Post: 01-28-2008, 01:12 PM
  3. how to delete or modify a record in a file?
    By danielhf in forum C++ Programming
    Replies: 2
    Last Post: 09-22-2003, 09:18 AM
  4. Delete a binary record
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 07-01-2002, 02:07 AM
  5. Replies: 2
    Last Post: 04-03-2002, 09:59 AM