Writing, reading and updating a binary file in C



#include
#include
#include
#include
#include
const int MAXLEN = 30; /* Size of name buffer */
const char *dirpath = "C:\\temp\\"; /* Directory path for file */
const char *file = "mydata.bin"; /* File name */
/* Structure encapsulating a name and age */
struct Record
{
char name[MAXLEN];
int age;
};
void listfile(char *filename); /* List the file contents */
void updatefile(char *filename); /* Update the file contents */
struct Record *getrecord(struct Record *precord); /* Read a record from stdin */
void getname(char *pname); /* Read a name from stdin */
void writefile(char *filename, char *mode); /* Write records to a file */
void writerecord(struct Record *precord, FILE *pFile);
struct Record * readrecord(struct Record *precord, FILE *pFile);
int findrecord(struct Record *precord, FILE *pFile);
void duplicatefile(struct Record *pnewrecord,
int index, char *filename, FILE *pFile);

int main(void)
{
char filename[strlen(dirpath)+strlen(file)+1]; /* Stores file path */
strcpy(filename, dirpath); /* Copy directory path */
strcat(filename, file); /* and append file name */
/* Choose activity option */
char answer = 'q';
while(true)
{
printf("\nChoose from the following options:"
"\nTo list the file contents enter L"
"\nTo create a new file enter C"
"\nTo add new records enter A"
"\nTo update existing records enter U"
"\nTo delete the file enter D"
"\nTo end the program enter Q\n : ");
scanf("\n%c", &answer);

switch(tolower(answer))
{
case 'l': /* List file contents */
listfile(filename);
break;
case 'c': /* Create new file */
writefile(filename,"wb+");
printf("\nFile creation complete.");
break;
case 'a': /* Append records */
writefile(filename, "ab+");
printf("\nFile append complete.");
break;
case 'u': /* Update existing records */
updatefile(filename);
break;
case 'd':
printf("Are you sure you want to delete %s (y or n)? ", filename);
scanf("\n%c", &answer);
if(tolower(answer) == 'y')
remove(filename);
break;
case 'q': /* Quit the program */
printf("\nEnding the program.", filename);
return 0;
default:
printf("Invalid selection. Try again.");
break;
}
}
return 0;
}

/* Read the name and age for a record from the keyboard */
struct Record *getrecord(struct Record *precord)
{
/* Verify the argument is good */
if(!precord)
{
printf("No Record object to store input.");
return NULL;
}

printf("\nEnter a name less than %d characters:", MAXLEN);
getname(precord->name); /* readf the name */

printf("Enter the age of %s: ", precord->name);
scanf(" %d", &precord->age); /* Read the age */
return precord;
}

/* Read a name from the keyboard */
void getname(char *pname)
{
fflush(stdin);
fgets(pname, MAXLEN, stdin); /* Read the name */
int len = strlen(pname);
if(pname[len-1] == '\n') /* if there's a newline */
pname[len-1] = '\0'; /* overwrite it */
}

/* Write a new record to the file at the current position */
void writerecord(struct Record *precord, FILE *pFile)
{
/* Verify the arguments are good */
if(!precord)
{
printf("No Record object to write to the file.");
return;
}
if(!pFile)
{
printf("No stream pointer for the output file.");
return;
}

/* Write the name & age to file */
size_t length = strlen(precord->name); /* Get name length */
fwrite(&length, sizeof(length), 1, pFile); /* Write name length */
fwrite(precord->name, sizeof(char), length, pFile); /* then the name */
fwrite(&precord->age, sizeof(precord->age), 1, pFile); /* then the age */
}

/* Reads a record from the file at the current position */
struct Record * readrecord(struct Record *precord, FILE *pFile)
{
/* Verify the arguments are good */
if(!precord)
{
printf("No Record object to store data from the file.");
return NULL;
}
if(!pFile)
{
printf("No stream pointer for the input file.");
return NULL;
}

size_t length = 0; /* Name length */
fread(&length, sizeof(length), 1, pFile); /* Read the length */
if(feof(pFile)) /* If it's end file */
return NULL; /* return NULL */

/* Verify the name can be accommodated */
if(length+1>MAXLEN)
{
fprintf(stderr, "\nName too long. Ending program.");
exit(1);
}

fread(precord->name, sizeof(char), length, pFile); /* Read the name */
precord->name[length] = '\0'; /* Append terminator */
fread(&precord->age, sizeof(precord->age), 1, pFile); /* Read the age */

return precord;
}

/* Write to a file */
void writefile(char *filename, char *mode)
{
char answer = 'y';

FILE *pFile = fopen(filename, mode); /* Open the file */
if(pFile == NULL) /* Verify file is open */
{
fprintf(stderr, "\n File open failed.");
exit(1);
}

do
{
struct Record record; /* Stores a record name & age */

writerecord(getrecord(&record), pFile); /* Get record & write the file */

printf("Do you want to enter another(y or n)? " );
scanf("\n%c", &answer);
fflush(stdin); /* Remove whitespace */
} while(tolower(answer) == 'y');

fclose(pFile); /* Close the file */
}

/* List the contents of the binary file */
void listfile(char *filename)
{
/* Create the format string for names up to MAXLEN long */
/* format array length allows up to 5 digits for MAXLEN */
char format[15]; /* Format string */
sprintf(format, "\n%%-%ds Age:%%4d", MAXLEN);

FILE *pFile = fopen(filename, "rb"); /* Open file to read */
if(pFile == NULL) /* Check file is open */
{
printf("Unable to open %s. Verify it exists.\n", filename);
return;
}

struct Record record; /* Stores a record */
printf("\nThe contents of %s are:", filename);

while(readrecord(&record, pFile) != NULL) /* As long as we have records */
printf(format, record.name, record.age); /* Output the record */

printf("\n"); /* Move to next line */

fclose(pFile); /* Close the file */
}

/* Modify existing records in the file */
void updatefile(char *filename)
{ char answer = 'y';

FILE *pFile = fopen(filename, "rb+"); /* Open the file for update */
if(pFile == NULL) /* Check file is open */
{
fprintf(stderr, "\n File open for updating records failed.");
return;
}

struct Record record; /* Stores a record */
int index = findrecord(&record, pFile); /* Find the record for a name */
if(index<0) /* If the record isn't there */
{
printf("\nRecord not found."); /* ouput a message */
return; /* and we are done. */
}

printf("\n%s is aged %d,", record.name, record.age);
struct Record newrecord; /* Stores replacement record */
printf("\nYou can now enter the new name and age for %s.", record.name);
getrecord(&newrecord); /* Get the new record */

/* Check if we can update in place */
if((strlen(record.name) == strlen(newrecord.name)))
{ /* Name lengths are the same so we can */
/* Move to start of old record */
fseek(pFile,
-(long)(sizeof(size_t)+strlen(record.name)+sizeof(record.age)),
SEEK_CUR);

writerecord(&newrecord, pFile); /* Write the new record */
fflush(pFile); /* Force the write */
}
else
duplicatefile(&newrecord, index, filename, pFile);

printf("File update complete.\n");
}

/* Duplicate the existing file replacing the record to be update */
/* The record to be replaced is index records from the start */
void duplicatefile(struct Record *pnewrecord, int index, char *filename, FILE *pFile)
{
/* Create and open a new file */
char tempname[L_tmpnam];
if(tmpnam(tempname) == NULL)
{
printf("\nTemporary file name creation failed.");
return;
}
char tempfile[strlen(dirpath)+strlen(tempname)+1];
strcpy(tempfile, dirpath); /* Copy original file path */
strcat(tempfile, tempname); /* Append temporary name */
FILE *ptempfile = fopen(tempfile, "wb+");

/* Copy first index records from old file to new file */
rewind(pFile); /* Old file back to start */
struct Record record; /* Store for a record */
for(int i = 0 ; i writerecord(readrecord(&record, pFile), ptempfile);


writerecord(pnewrecord, ptempfile); /* Write the new record */
readrecord(&record,pFile); /* Skip the old record */

/* Copy the rest of the old file to the new file */
while(readrecord(&record,pFile))
writerecord(&record, ptempfile);

/* close the files */
if(fclose(pFile)==EOF)
printf("\n Failed to close %s", filename);
if(fclose(ptempfile)==EOF)
printf("\n Failed to close %s", tempfile);

if(remove(filename)) /* Delete the old file */
{
printf("\nRemoving the old file failed. Check file in %s", dirpath);
return;
}

/* Rename the new file same as original */
if(rename(tempfile, filename))
printf("\nRenaming the file copy failed. Check file in %s", dirpath);
}

/* Find a record */
/* Returns the index number of the record */
/* or -1 if the record is not found. */
int findrecord(struct Record *precord, FILE *pFile)
{
char name[MAXLEN];
printf("\nEnter the name for the record you wish to find: ");
getname(name);

rewind(pFile); /* Make sure we are at the start */
int index = 0; /* Index of current record */

while(true)
{
readrecord(precord, pFile);
if(feof(pFile)) /* If end-of-file was reached */
return -1; /* record not found */
if(!strcmp(name, precord->name))
break;
++index;
}
return index; /* Return record index */
}


Related Links :

No comments:

Post a Comment


If you face any Problem in viewing code such as Incomplete "For Loops" or "Incorrect greater than or smaller" than equal to signs then please collect from My Web Site CLICK HERE


More Useful Topics...

 

History Of C..

In the beginning was Charles Babbage and his Analytical Engine, a machine
he built in 1822 that could be programmed to carry out different computations.
Move forward more than 100 years, where the U.S. government in
1942 used concepts from Babbage’s engine to create the ENIAC, the first
modern computer.
Meanwhile, over at the AT&T Bell Labs, in 1972 Dennis Ritchie was working
with two languages: B (for Bell) and BCPL (Basic Combined Programming
Language). Inspired by Pascal, Mr. Ritchie developed the C programming
language.

My 1st Program...


#include
#include
void main ()
{
clrscr ();
printf ("\n\n\n\n");
printf ("\t\t\t*******Pankaj *******\n");
printf ("\t\t\t********************************\n");
printf ("\t\t\t\"Life is Good...\"\n");
printf ("\t\t\t********************************");
getch ();
}

Next Step...


#include
#include

void main ()
{
clrscr ();
printf ("\n\n\n\n\n\n\n\n");
printf ("\t\t\t --------------------------- \n\n");

printf ("\t\t\t | IGCT, Info Computers, INDIA | \n\n");
printf ("\t\t\t --------------------------- ");

getch ();

}

Hits!!!