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.

Member Avatar for iamthwee

>gets(name);
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1049157810&id=1043284351

>clrscr();
Non portable

>while (!fil.eof())
Doesn't work as you expect it.

Modification of a file would be better achieved by creating a temporary buffer with all the changes then overwrite the original file.

It would also be better to use std::strings instead of char arrays.

>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 remove conio.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.

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...

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:

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...

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.

thanx...
problem solved

So what was the problem? How did you solve it? Your answer may help someone else later.

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...

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 over very carefully.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.