problem in modifying data in a binary file
hello everybody...
i am trying to make a project on binary files and that needs a function to modify data in a binary file. I have made the following class.
class example
{
public:
char name[10], number[5];
void getdetails();
void showdetails();
example()
{
name[0]='\0', number[0]='\0';
}
char* getname()
{
return name;
}
};
and the definition of mod_data() ( a function to modify data of the class ) is as follows:
void mod_data(example &abc)
{
char name[10], number;
cout<<"NAME: ";
gets(name);
if(strlen(name)!=0)
strcpy(abc.name, name);
cout<<"NUMBER: ";
gets(number);
if(strlen(number)!=0)
strcpy(abc.number, number);
}
to modify the record in the binary file, function modify is used
void modify()
{
int recc = 0;
int flag=0;
char name[25];
example abc;
clrscr();
fstream fil ("EXAMPLE.dat",ios::in);
cout<<"\n Enter The Name Of The Person Whose Details To Be Modified: ";
gets(name);
cout<<endl;
while (!fil.eof())
{
fil.read ((char*)&abc,sizeof(abc));
recc++;
if (stricmp(abc.getname(), name)==0)
{
flag=1;
break;
}
}
fil.close();
if(flag==1)
{
fil.open ("EXAMPLE.dat",ios::out|ios::ate);
mod_data(abc);
fil.seekp((recc-1)*sizeof(abc), ios::beg);
fil.write((char*)&abc,sizeof(abc));
fil.close();
}
else
{
cout<<"\n PERSON NOT FOUND";
getch();
}
}
but the program is not working properly.
in my original class there are more than 15 data members. And what i want to do is if the user presses enter in a particular field the record for that field which was present before remains as it is i.e. that field is not modified. But the function works properly for only the first few data members and not for the last ones.The last data members when displayed appear blank or garbage data is displayed. Please help me out.
tracethepath
Junior Poster in Training
54 posts since Jul 2007
Reputation Points: 8
Solved Threads: 4
iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
>gets(name);
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1049157810&id=1043284351
Yes, gets() is a very dangerous function, as is scanf("%s",...) in exactly the same way.>clrscr();
Non portable
As is getch() . Best to removeconio.h completely and use no functions from it because most compilers won't be able to compile your programs.
>while (!fil.eof())
Doesn't work as you expect it.
For further information, see this , .eof() is exactly like feof() Modification of a file would be better achieved by creating a temporary buffer with all the changes then overwrite the original file.
Another alternative is to simply write each record to a new file. When done, the program can delete the original file and rename the new file. This will also save all the file pointer stuff you're doing now, making the code much simpler and safer.
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
Another alternative is to simply write each record to a new file. When done, the program can delete the original file and rename the new file. This will also save all the file pointer stuff you're doing now, making the code much simpler and safer.
as told by you i used the following code but if the record to be modified is the last record it works fine, but if its the record somewhere in between then the rest of the records i.e. the records after that record are deleted.
void modify()
{
int flag=0;
char name[10];
example xyz;
clrscr();
ifstream fin("EXAMPLE.dat", ios::binary);
ofstream fout("temp.dat", ios::binary);
cout<<"\n Enter The Person's Name Whose Details To Be Modified: ";
gets(name);
cout<<endl;
while (fin)
{
if(!fin.read((char*)&xyz, sizeof(xyz)))
break;
if(stricmp(xyz.getname(), name)!=0)
fout.write((char*)&xyz, sizeof(xyz));
if (stricmp(xyz.getname(), name)==0)
{
flag=1;
mod_data(xyz);
fout.write((char*)&xyz, sizeof(xyz));
}
}
fin.close();
fout.close();
remove("EXAMPLE.dat");
rename("temp.dat", "EXAMPLE.dat");
if(flag==0)
{
cout<<"\nPERSON NOT FOUND";
getch();
}
}
thanx...
tracethepath
Junior Poster in Training
54 posts since Jul 2007
Reputation Points: 8
Solved Threads: 4
Did you read and write the rest of the file? Or did you think the records past the last one you read would magically move over to the new file? :icon_wink:
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
Did you read and write the rest of the file? Or did you think the records past the last one you read would magically move over to the new file? :icon_wink:
sir, sorry i cant understand you...
i have put that in the while loop, so after modifying the data it the loop will run again and rest of the records will be written...
if i am not right...
please tell me the appropriate correction...
thanks...
tracethepath
Junior Poster in Training
54 posts since Jul 2007
Reputation Points: 8
Solved Threads: 4
OK, I looked more closely at your code. I made an assumption before.
#1) I see you're still using the getch() , clrscr() , and the evil gets() . Bad. Very bad. You're writing C++. Stop using C.
#2) In the loop, the code
if(stricmp(xyz.getname(), name)!=0)
{
...
}
if (stricmp(xyz.getname(), name)==0)
{
...
}
is the same as
if(stricmp(xyz.getname(), name)!=0)
{
...
}
else
{
...
}
Use the else version -- it's easier to read.
You're saying the code you posted isn't working? Then add some output statements to watch the program's flow and see where it seems to be going wrong.
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
tracethepath
Junior Poster in Training
54 posts since Jul 2007
Reputation Points: 8
Solved Threads: 4
So what was the problem? How did you solve it? Your answer may help someone else later.
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
i don't know what the problem was...i just replaced that if statement by else and put some output statements there to keep a check and it worked fine...
tracethepath
Junior Poster in Training
54 posts since Jul 2007
Reputation Points: 8
Solved Threads: 4
Ahhh, code gremlins strike again!!!!
Sounds like you still have a problem -- and I'll bet gets() has something to do with it. You are probably overrunning an array somewhere. Like entering 10 or more characters into a character array defined as 10...
Might want to check your code oververy carefully.
WaltP
Posting Sage w/ dash of thyme
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944