ورود

نسخه کامل مشاهده نسخه کامل : حذف یک struct از یک فایل باینری



Mt.Shadow
02-01-2013, 20:10
سلام
چطوری میتونم یه struct رو در یک فایل باینری جستجو و بعدش اونو حذف کنم.
و بعد از این که حدفش کردم جای اون رو تو فایل شیفت بدم یعنی این که کل داده ها به اندازه ی struct شیفت داده بشه بعدش اخره فایل به اندازه اون struct خالی میشه (اگه اشتباه نکنم)
بعدش اون قسمت خالی هم حدف بشه ؟؟؟
امیدوارم مفهوم رو رسونده باشم !

Mt.Shadow
04-01-2013, 20:27
سلام
چطوری میتونم یه struct رو در یک فایل باینری جستجو و بعدش اونو حذف کنم.
و بعد از این که حدفش کردم جای اون رو تو فایل شیفت بدم یعنی این که کل داده ها به اندازه ی struct شیفت داده بشه بعدش اخره فایل به اندازه اون struct خالی میشه (اگه اشتباه نکنم)
بعدش اون قسمت خالی هم حدف بشه ؟؟؟
امیدوارم مفهوم رو رسونده باشم !

یعنی اینقدر سخته این کار که هیچکی جواب نمیده؟ :n15:
خواهشا" اگه کسی بلده بگه !

god of war 2
04-01-2013, 23:53
سلام.
جواب سوالتون ساده هست وشاید افراد زیادی در اینجا بتونن پاسخ بدن اما سوالتون خیلی کلی هست و در حد یک برنامه چند صد خطی هست که به روش های خیلی زیادی هم قابل پیاده سازی هست. پس بنابراین نمیشه جواب ثابت و کاملی داد اما چند راهنمایی کوچیک میشه کرد که احتمالا مفید هست.
اگر سوالتون به بخش های کوچیک تقسیم کنیم, شما به عملیاتی مثل زیر نیاز دارید:
1- نوشتن یک struct
2- خواندن/جستجوی یک struct
3- حذف/شیفت یک struct

هرکدام ار کار های بالا به روش های مختلفی قابل پیاده سازی هست.
بنده به ترتیب از هر کدام یک مثال میزنم ولی کدی نمینویسم و امیدوارم بدردتون بخوره.
1- در ++C استاندارد قابلیت serialize یک ساختمان داده پیچیده به تنهایی وجود ندارد. یعنی شما نمیتوانید یک struct پیچیده رو به تنهایی و بدون هیچ کار اضافه ایی توسط توابع IO استاندارد در یک فایل بنویسید(این کار با استفاده از کتابخانه عظیم boost امکان پذیر میباشد) . اما برای یک struct ساده که مثلا از چند مقدار int تشکیل شده است کار فرق میکند. ابتدا باید یک فرمت برای فایل خود ایجاد کنید. در ساده ترین حالت ممکن یک فایل میتونه شامل رکوردهایی با اندازه ثابت باشه که این اندازه میتونه همان اندازه struct شما باشه. پس تا اینجا باید اندازه struct خود را بدست بیارید و هر شی را در یک رکورد با اندازه ثابت ذخیره کنید.

2- همواره برای جستجو باید یک شرط وجود داشته باشد.(مثلا مقدار x3 == 2 باشد)
شما میتوانید از الگوریتم های مختلف جستجو مانند ترتیبی یا درخت دودویی استفاده کنید. البته در الگوریتم دودویی رکوردها باید به ترتیب ذخیره شده باشند.
برای جسجتو مثلا به روش ترتیبی شما باید از رکورد اول یعنی به اندازه ثابتی (به اندازه Struct) از فایل را بخوانید و در یک struct قرار بدید سپس آن را با شرط جسجتجو مقایسه کنید, اگر شرط برقرار بود که رکورد مورد نظر پیدا شده و اگر شرط برقرار نبود باید دقیقا از خانه بعد از رکورد اول به اندازه ثابت تعیین شده مجددا از فایل بخونید و در struct بریزید سپس مانند قبل مقایسه و ....

3- برای حذف یک struct باید شماره رکورد آن را بدست بیاورید. این بدست آوردن شماره میتونه با یک جسجتو انجام بشه که در مطلب قبلی گفتم. برای مثال اگر طول هر رکورد 8 بایت باشد و شما میخواهید رکورد 5 را حذف کنید باید اول آدرس رکورد را بصورت 6*8 محاسبه کنید و به میزان 48 بایت در فایل پیش برید سپس به اندازه 8 بایت (که همان رکورد حذف شده میباشد) باید تمام رکورد های جلوتر را به عقب شیف کنید.

اگر سوالی داشتید لطفا دقیق و جزئی بپرسید تا بهتر بشه راهنمایی کرد. معمولا سوالات کلی و مفصل وقت زیادی برای پاسخ میخواهند.

Mt.Shadow
05-01-2013, 11:33
سلام.
جواب سوالتون ساده هست وشاید افراد زیادی در اینجا بتونن پاسخ بدن اما سوالتون خیلی کلی هست و در حد یک برنامه چند صد خطی هست که به روش های خیلی زیادی هم قابل پیاده سازی هست. پس بنابراین نمیشه جواب ثابت و کاملی داد اما چند راهنمایی کوچیک میشه کرد که احتمالا مفید هست.
اگر سوالتون به بخش های کوچیک تقسیم کنیم, شما به عملیاتی مثل زیر نیاز دارید:
1- نوشتن یک struct
2- خواندن/جستجوی یک struct
3- حذف/شیفت یک struct

هرکدام ار کار های بالا به روش های مختلفی قابل پیاده سازی هست.
بنده به ترتیب از هر کدام یک مثال میزنم ولی کدی نمینویسم و امیدوارم بدردتون بخوره.
1- در ++C استاندارد قابلیت serialize یک ساختمان داده پیچیده به تنهایی وجود ندارد. یعنی شما نمیتوانید یک struct پیچیده رو به تنهایی و بدون هیچ کار اضافه ایی توسط توابع IO استاندارد در یک فایل بنویسید(این کار با استفاده از کتابخانه عظیم boost امکان پذیر میباشد) . اما برای یک struct ساده که مثلا از چند مقدار int تشکیل شده است کار فرق میکند. ابتدا باید یک فرمت برای فایل خود ایجاد کنید. در ساده ترین حالت ممکن یک فایل میتونه شامل رکوردهایی با اندازه ثابت باشه که این اندازه میتونه همان اندازه struct شما باشه. پس تا اینجا باید اندازه struct خود را بدست بیارید و هر شی را در یک رکورد با اندازه ثابت ذخیره کنید.

2- همواره برای جستجو باید یک شرط وجود داشته باشد.(مثلا مقدار x3 == 2 باشد)
شما میتوانید از الگوریتم های مختلف جستجو مانند ترتیبی یا درخت دودویی استفاده کنید. البته در الگوریتم دودویی رکوردها باید به ترتیب ذخیره شده باشند.
برای جسجتو مثلا به روش ترتیبی شما باید از رکورد اول یعنی به اندازه ثابتی (به اندازه Struct) از فایل را بخوانید و در یک struct قرار بدید سپس آن را با شرط جسجتجو مقایسه کنید, اگر شرط برقرار بود که رکورد مورد نظر پیدا شده و اگر شرط برقرار نبود باید دقیقا از خانه بعد از رکورد اول به اندازه ثابت تعیین شده مجددا از فایل بخونید و در struct بریزید سپس مانند قبل مقایسه و ....

3- برای حذف یک struct باید شماره رکورد آن را بدست بیاورید. این بدست آوردن شماره میتونه با یک جسجتو انجام بشه که در مطلب قبلی گفتم. برای مثال اگر طول هر رکورد 8 بایت باشد و شما میخواهید رکورد 5 را حذف کنید باید اول آدرس رکورد را بصورت 6*8 محاسبه کنید و به میزان 48 بایت در فایل پیش برید سپس به اندازه 8 بایت (که همان رکورد حذف شده میباشد) باید تمام رکورد های جلوتر را به عقب شیف کنید.

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



برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

بعدش ما عمل جستجو رو با یه حلقه که شرط اون رسیدن به پایان فایل هست انجام میدیم
تو این قسمت چطوری میتونیم اون struct رو حذف یا اصلا" ویرایش کنیم.

god of war 2
05-01-2013, 16:59
خوب من براتون یه کد ساده نوشتم و عملیات نوشتن/خواندن/ویرایش رو میتونید در آن مشاهده کنید. (قبل از هر چیز بگم که کدهایی که بنده نوشته ام فقط جنبه آموزشی دارند و به هیچ وجه استفاده از آنها در برنامه های غیرآموزشی توصیه نمیشود)
------
اما میرسیم به مبحث حذف که کلا یک بحث جداگانه داره. در حقیقت چیزی به نام حذف اطلاعات در سیستم های کامپیوتری وجود ندارد! اصلا واژه حذف کردن/پاک کردن/delete/.... به آن معنی که ظاهران هستند عمل نمیکنند و در اصل اعمال دیگری پشت این کلمات وجود دارد.( اگر از پایین ترین سطح به آن نگاه کنیم یک HardDisk هیچگاه داده ایی را حذف نمیکند بلکه به روشهای مختلفی آن را نادیده میگیرد و اجازه نوشتن مجدد بر روی آن قسمت را میدهد)
اما در رابطه با این موضوع چندتا راه مختلف وجود دارد که هرکدام ویژگی های خودشونو رو دارند. زمانی که شما بصورت باینری به یک فایل دسترسی پیدا میکنید, برنامه شما تمام اطلاعات موجود در فایل رو بصورت بایت میبیند و مثلا چیزی به عنوان جمله یا کلمه و یا کاراکتر های backspace و ... وجود ندارد.یعنی نمیتوانید مانند یک فایل متنی اطلاعات رو پاک کنید.اما میتونید مثلا یک رکورد رو کلا با کاراکتر "0/"
پر کنید یا مثلا برای هر رکورد یک فلگ حذف قرار بدید و اگر رکوردی فلگ حذف داشت در اصل آن رکورد از دید برنامه پاک شده بحساب میاد و ...
برای shift دادن اطلاعات شما میتوانید با یک محاسبه ساده تعداد رکورد های موجود رو بدست بیارید بعد تمامی رکوردهای بعد از رکورد پاک شده رو بخوانید سپس اشارگر نوشتن رو بر روی ابتدای رکورد پاک شده قرار بدید سپس تمام رکرودهای خوانده شده رو بنویسید و در آخر هم رکوردهای تکراری رو از انتهای فایل پاک کنید(به همان شکلی که گفتم مثلا با کاراکتر "0/" پر کنید.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

Mt.Shadow
05-01-2013, 17:38
خوب من براتون یه کد ساده نوشتم و عملیات نوشتن/خواندن/ویرایش رو میتونید در آن مشاهده کنید. (قبل از هر چیز بگم که کدهایی که بنده نوشته ام فقط جنبه آموزشی دارند و به هیچ وجه استفاده از آنها در برنامه های غیرآموزشی توصیه نمیشود)
------
اما میرسیم به مبحث حذف که کلا یک بحث جداگانه داره. در حقیقت چیزی به نام حذف اطلاعات در سیستم های کامپیوتری وجود ندارد! اصلا واژه حذف کردن/پاک کردن/delete/.... به آن معنی که ظاهران هستند عمل نمیکنند و در اصل اعمال دیگری پشت این کلمات وجود دارد.( اگر از پایین ترین سطح به آن نگاه کنیم یک HardDisk هیچگاه داده ایی را حذف نمیکند بلکه به روشهای مختلفی آن را نادیده میگیرد و اجازه نوشتن مجدد بر روی آن قسمت را میدهد)
اما در رابطه با این موضوع چندتا راه مختلف وجود دارد که هرکدام ویژگی های خودشونو رو دارند. زمانی که شما بصورت باینری به یک فایل دسترسی پیدا میکنید, برنامه شما تمام اطلاعات موجود در فایل رو بصورت بایت میبیند و مثلا چیزی به عنوان جمله یا کلمه و یا کاراکتر های backspace و ... وجود ندارد.یعنی نمیتوانید مانند یک فایل متنی اطلاعات رو پاک کنید.اما میتونید مثلا یک رکورد رو کلا با کاراکتر "0/"
پر کنید یا مثلا برای هر رکورد یک فلگ حذف قرار بدید و اگر رکوردی فلگ حذف داشت در اصل آن رکورد از دید برنامه پاک شده بحساب میاد و ...
برای shift دادن اطلاعات شما میتوانید با یک محاسبه ساده تعداد رکورد های موجود رو بدست بیارید بعد تمامی رکوردهای بعد از رکورد پاک شده رو بخوانید سپس اشارگر نوشتن رو بر روی ابتدای رکورد پاک شده قرار بدید سپس تمام رکرودهای خوانده شده رو بنویسید و در آخر هم رکوردهای تکراری رو از انتهای فایل پاک کنید(به همان شکلی که گفتم مثلا با کاراکتر "0/" پر کنید.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

خیلی ممنون دوست عزیز
ولی خطا میده
تست کردی شما ؟

god of war 2
05-01-2013, 17:45
از چه کامپایلری استفاده میکنید؟
دقیقا چه خطایی میدهد؟
اینم فایل کامپایل شده:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

Mt.Shadow
05-01-2013, 17:51
از چه کامپایلری استفاده میکنید؟
دقیقا چه خطایی میدهد؟
اینم فایل کامپایل شده:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

با Visual Studio 2012 خطا میداد الان با CodeBlocks تست کردم مشکلی نداشت
ممنون.

Mt.Shadow
05-01-2013, 17:56
فقط یه سوال ؟
چرا تو خط 4 تابع PrintFile بدون استفاده از اشاره گر یه آرایه پویا تعریف کردید ولی تو CodeBlocks هیچ Error نداد؟

god of war 2
05-01-2013, 18:06
با Visual Studio 2012 خطا میداد الان با CodeBlocks تست کردم مشکلی نداشت
ممنون.
خطوط:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
را به این شکل تغییر دهید :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

و کدها در VS 2012 هم کامپایل خواهد شد.

ویرایش:
در آخر شرط و بعد از حلقه for یادتون باشه که

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
رو اضافه کنید.
----------
ویرایش

چرا تو خط 4 تابع PrintFile بدون استفاده از اشاره گر یه آرایه پویا تعریف کردید ولی تو CodeBlocks هیچ Error نداد؟
کامپایلر ها ساختارشون با یکدیگر تفاوت داره. بعضی از کامپایلر ها با یکسری از مسائل طور دیگری برخورد میکنند و اونو به نحوی حل میکنند اما بعضی دیگر حساس تر هستند و از مسائل جزئی هم اشکال میگیرند ولی در کل بهتره یک کد در درست ترین حالت ممکن نوشته بشه.