PDA

View Full Version : سوال: درخواست کمک فوری در مورد فایل ها



mehdi_r2
پنج شنبه 20 تیر 1387, 14:54 عصر
سلام
من یه برنامه ای نوشتم که مشخصات n دانشجو رو میگیره وذخیره میکنه چون در مورد فایل زیاد اطلاعی ندارم نمیدونم چه جوری میشه یه رکورد رو حذف کرد ممنون میشم اگه کسی توضیح کاملی بده در ضمن تابع جستجو رو هم نوشتم فقط نمیتونم رکوردی رو حذف کنم

emad_67
پنج شنبه 20 تیر 1387, 16:24 عصر
برای حدف رکورد باید به اون یه برچسب بدی که به عنوان رکورد حذف شده در نظر گرفته بشه، چون عملا نمیشه رکورد رو از فایل حذف کرد. به طور مثال اگه اطلاعات رو در کلاس یا struct تعریف کردی میتونی یه پارامتر به عنوان رکورد حذف شده توی اون در نظر بگیری که نشون دهنده حذف رکورد باشه. حالا وقتی که خواستی رکورد رو حدف کنی ابتدا باید اونو بخون و بعد با مثلا دادن مقدار 1 به اون پارامتر مشخص کنی که رکورد حذف شده هست. بعد هم اونو مجددا روی رکورد فعلی توی فایل ذخیره کنی. می تونی اصلا پارامتر اضافه ای در نظر نگیری و مثلا شماره دانشجویی طرف رو یع مقدار منفی قرار بدی و ....
اینا کلیات بود ، اگه تو پیاده سازیش مشکل داشته بگو.

mehdi_r2
جمعه 21 تیر 1387, 13:53 عصر
اول ممنون از کمکی که کردین حالا یه سئوال دارم اگه اینم جواب بدین ممنون میشم .
میخواستم بدونم اون رکوردی رو که براش برچسب گذاشتیم میشه یه رکورد دیگه رو روش نوشت یا باید همونجوری بمونه

mehdad.koulab
جمعه 21 تیر 1387, 14:19 عصر
اول ممنون از کمکی که کردین حالا یه سئوال دارم اگه اینم جواب بدین ممنون میشم .
میخواستم بدونم اون رکوردی رو که براش برچسب گذاشتیم میشه یه رکورد دیگه رو روش نوشت یا باید همونجوری بمونه
سلام دوست عزیز
نه شما نمیتونی روی اون چیزی بنویسی چون همون طور که دوستمون گفت فقط برچسب حذف میخوره و به طور واقعی حذف نمیشه ولی برای باز پس گیری این حافظه که بهش حافظه حرض میگن میتونی از سازمان دهی مجدد فایل استفاده کنی که هم حافظه رو برمیگردونه هم فایل رو پاک میکنه.

emad_67
شنبه 22 تیر 1387, 10:10 صبح
اول ممنون از کمکی که کردین حالا یه سئوال دارم اگه اینم جواب بدین ممنون میشم .
میخواستم بدونم اون رکوردی رو که براش برچسب گذاشتیم میشه یه رکورد دیگه رو روش نوشت یا باید همونجوری بمونه
سلام دوست عزیز
نه شما نمیتونی روی اون چیزی بنویسی چون همون طور که دوستمون گفت فقط برچسب حذف میخوره و به طور واقعی حذف نمیشه ولی برای باز پس گیری این حافظه که بهش حافظه حرض میگن میتونی از سازمان دهی مجدد فایل استفاده کنی که هم حافظه رو برمیگردونه هم فایل رو پاک میکنه.اتفاقا بر عکس، میشه روی اون رکوردی که به عنوان حذف شده علامت خورده یه رکورد دیگه رو نوشت، فقط کافیه اشاره گر جریان خروجی رو روی اون بایتی که رکورد حذف شده از اون جا شروع میشه قرار بدی و فقط رکورد جدید رو روش write کنی.

soroush68
سه شنبه 25 تیر 1387, 18:55 عصر
علامت زدن یک رکورد در یک فایل روشیه که عملا اون رکورد رو حذف نمی کنه. بلکه یه علامت میذاره که در موقع خوندن اون رو ندیده بگیریم. در این صورت حجم بی خودی اشغال میشه.
یه روش دیگه برای حذف یک رکورد از فایل باینری وجود داره :
تعداد رکورد های داخل فایل رو بشماریم. تعداد n رکورد در فایل وجود دارد.
به تعداد n-1 آبجکت از نوع همان رکورد ها تخصیص حافظه می کنیم.
به ترتیب از ابتدای فایل تا آخر فایل رکورد ها را به جز رکوردی که قرار است حذف شود خوانده و در آبجکت ها ی همنوع read شوند(قرار داده شوند)
فایل رو بسته و دوباره باز می کنیم و طول فایل رو صفر می کنیم. ios::trunc
یکی یکی تمام آبجکت هایی که از فایل ابتدایی خوندیم در این فایل جدید که همنام همان فایل قبلی است ذخیره می کنیم.
(به طور خلاصه تمام رکورد ها به جز رکوردی که قرار است حذف شود رو روی یک فایل همنام جدید ذخیره می کنیم)

RF.Ariyapoor
چهارشنبه 09 مرداد 1387, 00:00 صبح
اتفاقا بر عکس، میشه روی اون رکوردی که به عنوان حذف شده علامت خورده یه رکورد دیگه رو نوشت، فقط کافیه اشاره گر جریان خروجی رو روی اون بایتی که رکورد حذف شده از اون جا شروع میشه قرار بدی و فقط رکورد جدید رو روش write کنی.

این چیزی که گفتی شدیدا جالبه یه کم در موردش توضیح بده

emad_67
چهارشنبه 09 مرداد 1387, 09:51 صبح
این چیزی که گفتی شدیدا جالبه یه کم در موردش توضیح بدههمون طور که گفتم توی فایل فقط باید جای اشاره گر جریان خروجی رو تنظیم کنی و رکورد هایی رو که میخوای در اون ذخیره کنی.
مثلا فرض کن یه همچین ساختاری داریم:


struct student
{
int number;
char name[20];
};
توی این ساختار متغیر number رو که همون شماره دانشجویی طرف هست در نظر گرفتم.
حالا یه متغیر از این ساختار می سازیم و بعد از اینکه اطلاعات رو از ورودی دریافت کردیم اونو در فایل ذخیره می کنیم:


fstream inout("record.dat",ios::in | ios::out);
student t;
cin>>t.number;
cin>>t.name;
inout.seekp(0);
inout.write(reinterpret_cast<const char *>(&t),sizeof(student));
در اینجا من اشاره گر جریان خروجی (seekp) روی روی بایت 0 قرار دادم و از اونجا به اندازه حجم ساختار student اون رکورد رو در فایل ذخیره کردم.
حالا فرض کن میخوایم این رکورد رو حذف کنیم. برای اینکار می یایم ابتدا اشاره گر جریان ورودی(seekg) رو روی بایت 0 ام قرار میدیم و از اونجا به اندازه حجم ساختار student میخونیم:


student t;
inout.seekg(0);
inout.read(reinterpret_cast<char *>(&t),sizeof(student));
حالا خیلی راحت میتونی رکورد خونده شده رو که در متغیر تعریف شده از ساختار student قرار گرفته رو ویرایش کنی. مثلا برای اینکه این رکورد رو خدف شده اعلام کنی میتونی شماره این دانشجو رو 0 یا -1 قرار بدی:


t.number=0;
و مجددا مثل مرحله اول اشاره گر رو در بایت 0 ام قرار بدی و همین رکورد رو در فایل بر روی رکورد قبلی ذخیره کنی. با این کار رکوردت از نظر شما حذف شده است(همچنان در فایل موجود و حجمی به خودش اختصاص داده) و میتونی با تنظیم اشاره گر فایل یه رکورد جدید رو بر روی اون ذخیره کنی. مثل همین کاری که اینجا انجام دادم.
این ساختار که چه جوری یه رکورد رو خدف شده در نظر بگیری بستگی به خودت داره. مثلا در مورد این مثال به نظرم 0 کردن شماره داشنجویی بهتر بود ولی ممکنه توی یه مثال دیگه انجام یه کار دیگه بهتر باشه.