نمایش نتایج 1 تا 3 از 3

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

  1. #1

    Question مشکل با آبجکت آخر ذخیره شده در یک فایل باینری

    سلام دوستان عزیز
    کد زیر یه برنامه ی ساده است که آبجکت هایی رو میگیره و در یک فایل ذخیره میکنه. بنابه درخواست میتونه اونا رو ادیت کنه یا با علامتگذاری در شی مورد نظر به نوعی اون رو پاک کنه. مساله اینجاست که ادیت و دیلیت کردن در مورد شی آخر فایل عمل نمی کند. این اشکال فقط در مورد آبجکت آخر ذخیره شده در فایل پیش میاد. برای درک بهتر مساله بهتره کد رو اجرا کنید چند آبجکت را در فایل ذخیره کنید و مساله ادیت یا پاک کردن اونا رو امتحان کنید.
    ضمنا به خاطر کد طولانی که ممکنه خوندنش وقت گیر بشه عذر میخوام

    /****************************************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::ap p);
    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();
    }

  2. #2
    کاربر دائمی
    تاریخ عضویت
    اسفند 1385
    محل زندگی
    تهران
    پست
    1,486

    نقل قول: مشکل با آبجکت آخر ذخیره شده در یک فایل باینری

    تابع 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) به دست بیار.

  3. #3

    نقل قول: مشکل با آبجکت آخر ذخیره شده در یک فایل باینری

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

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •