PDA

View Full Version : مشکل با آبجکت آخر ذخیره شده در یک فایل باینری



soroush68
جمعه 21 تیر 1387, 18:38 عصر
سلام دوستان عزیز :لبخندساده:
کد زیر یه برنامه ی ساده است که آبجکت هایی رو میگیره و در یک فایل ذخیره میکنه. بنابه درخواست میتونه اونا رو ادیت کنه یا با علامتگذاری در شی مورد نظر به نوعی اون رو پاک کنه. مساله اینجاست که ادیت و دیلیت کردن در مورد شی آخر فایل عمل نمی کند. این اشکال فقط در مورد آبجکت آخر ذخیره شده در فایل پیش میاد. :متفکر: برای درک بهتر مساله بهتره کد رو اجرا کنید چند آبجکت را در فایل ذخیره کنید و مساله ادیت یا پاک کردن اونا رو امتحان کنید.
ضمنا به خاطر کد طولانی که ممکنه خوندنش وقت گیر بشه عذر میخوام :چشمک:



/****************************************HeaderFile s*/

#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <stdio.h>

/****************************************Class definition*/

class pay
{
public:
char tit[80],det[400];
float c;
int y,m,d;
pay(){};
void getdata();
void showdata();
};
void pay::getdata()
{
cout<<"Title: ";
gets(tit);
cout<<"Cost: ";
cin>>c;
cout<<"Date: ";
do{
cout<<"\n Year: ";
cin>>y;
}while(y<1380||y>1400);
do{
cout<<" Month: ";
cin>>m;
}while(m>12||m<1);
if(m>0&&m<7)
do{
cout<<" Day: ";
cin>>d;
}while(d>31||d<1);
if(m>6&&m<12)
do{
cout<<" Day: ";
cin>>d;
}while(d>30||d<1);
if(m==12&&y%4==3)
do{
cout<<" Day: ";
cin>>d;
}while(d>30||d<1);
if(m==12&&y%4!=3)
do{
cout<<" Day: ";
cin>>d;
}while(d>29||d<1);
cout<<"Det: ";
gets(det);
}
void pay::showdata()
{
cout<<"Title: ";
puts(tit);
cout<<"Cost: "<<c;
cout<<"\nDate: "<<y<<" / "<<m<<" / "<<d;
if(det[0])
{
cout<<"\nDetails: ";
puts(det);
cout<<endl;
for(int m=0;m<75;m++)
cout<<"*";
return;
}
cout<<endl<<endl;
for(int m=0;m<75;m++)
cout<<"*";
}

/****************************************function prototypes*/

void enter();
void view();
void edit();
void del();

/****************************************Main function*/

void main()
{
char ans;
while(1)
{
clrscr();
cout<<"1)Enter\n2)View\n3)Edit\n4)Delete\n5)Exit";
ans=getch();
switch(ans)
{
case '1': enter(); break;
case '2': view(); break;
case '4': del(); break;
case '3': edit(); break;
case '5': return;
}
}
}

/****************************************functions definition*/

void enter()
{
clrscr();
pay p;
fstream f;
f.open("Datafile.dat",ios::out|ios::binary|ios::app);
p.getdata();
f.write((char*) &p,sizeof(pay));
f.close();
return;
}


void view()
{
clrscr();
int i=0;
fstream f;
pay p;
f.open("Datafile.dat",ios::in|ios::binary);
while(f.read((char*) &p,sizeof(pay)))
{
if(p.d!=0)
{
cout<<++i<<":\n";
p.showdata();
cout<<"\n\n";
}
}
f.close();
getch();
}


void edit()
{
clrscr();
clrscr();
int n,i=0,e=0;
pay p;
fstream f;
f.open("Datafile.dat",ios::in|ios::out|ios::binary);
cout<<"Enter num of record to edit: ";
cin>>n;
while(f.read((char*) &p,sizeof(pay))&&i<n)
{
if(p.d==0)
{
e++;
i--;
}
i++;
}
n=n+e-1;
f.seekg(n*sizeof(pay));
f.read((char*)&p,sizeof(pay));
cout<<"\n\n";
p.showdata();
char ans;
cout<<"\nAre you sure to edit? <y>";
ans=getch();
if(ans!='y')
return;
cout<<"\n\n";
p.getdata();
f.seekp(n*sizeof(pay));
f.write((char*) &p,sizeof(pay));
f.close();
}


void del()
{
clrscr();
int n,i=0,e=0;
pay p;
fstream f;
f.open("Datafile.dat",ios::in|ios::out|ios::binary);
cout<<"Enter num of record to delete: ";
cin>>n;
while(f.read((char*) &p,sizeof(pay))&&i<n)
{
if(p.d==0)
{
e++;
i--;
}
i++;
}
n=n+e-1;
f.seekg(n*sizeof(pay));
f.read((char*)&p,sizeof(pay));
cout<<"\n\n";
p.showdata();
char ans;
cout<<"\nAre you sure to delete? <y>";
ans=getch();
if(ans!='y')
return;
p.d=0;
f.seekp(n*sizeof(pay));
f.write((char*) &p,sizeof(pay));
f.close();
}

emad_67
شنبه 22 تیر 1387, 10:22 صبح
تابع del رو یه خط بهش ادیت کردم:


void del()
{
system("cls");
cout<<flush;
int n,i=0,e=0;
pay p;
fstream f;
f.open("Datafile.dat",ios::in|ios::out|ios::binary);
cout<<"Enter num of record to delete: ";
cin>>n;
while(f.read((char*) &p,sizeof(pay))&&i<n)
{
if(p.d==0)
{
e++;
i--;
}
i++;
}
n=n+e-1;
f.seekg(n*sizeof(pay));
f.read((char*)&p,sizeof(pay));
cout<<"\n\n";
p.showdata();
char ans;
cout<<"\nAre you sure to delete? <y>";
ans=getch();
if(ans!='y')
return;
p.d=0;
f.clear();
f.seekp(n*sizeof(pay));
f.write((char*) &p,sizeof(pay));
f.close();
}
قبل از جایی که میخوای seekp رو تنظیم کنی یه f.clear() قرار بده تا موقعیت اشاره گر فایل ریست بشه و این مشکل پیش نیاد.
ضمنا یه راه ساده تر برای اینکه این حلقه رو هم ننویسی:


while(f.read((char*) &p,sizeof(pay))&&i<n)
{
if(p.d==0)
{
e++;
i--;
}
i++;
}
اینه که تعداد کل رکورد ها ( حذف شده ها رو به حساب نیار) رو در 4 بایت اون فایل ذخیره کنی و دفعه بعد که اونو باز کردی ابتدا 4 بایت اول رو بخونی و .... در حال حاضر وقتی رکوردی از فایل حذف میشه حافظه اون همچنان در فایل باقی هست ولی در صورتی که این روشی رو که گفتم انجام بدی می تونی رکورد های جدید رو روی رکورد های پاک شده ذخیره کنی تا عملا حافظه ای برای رکورد های حذفی هدر نره. ضمنا برای استفاده از این روش فایل رو به صورت ios::out به جای ios::app باز کن و موقیت اشاره گر رو با همون n* sizeof(pay) به دست بیار.

soroush68
شنبه 22 تیر 1387, 12:33 عصر
ممنون از راهنماییت.
ضمنا علاوه بر راهی که گفتی میشه تابع enter() رو به همان صورت به کار برد اما در تابع del() تمام رکورد ها را به جز آنهایی که قرار است پاک شوند در یک آرایه از آبجکت ها ذخیره و سپس در یک فایل به همان نام اولیه ذخیره کنیم.