الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيف أريد أن أتعامل مع أنواع بيانات مختلفة في الملفات(لو تكرمتوا)*

مغلق
بدأه azzoz2 في 9 يناير 2008 · 21 رد · 1,865 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

مساكم الله بالخير

أنا يا إخوان طالب ومكلف بعمل مشروع يتعامل مع قاعدة بيانات . أنواع البيانات فيها غير معروف وأيضا عدد الأعمدة قيطلب من المستخدم إدخال عدد الأعمدة ونوع كل عمود مع اسمه

فينشئ البرنامج متغيرات بحسب عدد وأنواع الاعمدة التي أدخلها المستخدم

وأيضا هناك برنامج آخر يقرأ ملفات البرنامج الأول ويقوم بالبحث والعرض

لكن الصعوبة في: كيف يعرف البرنامج الثاني نوع البيانات التي يقرأها من الملف لكي ينشأ متغير خاص بها ونفس نوعها....؟؟؟؟؟؟؟؟؟؟

أرجوا أن يكون السؤال واضحا .....

والمشروع مرفق لمن أراد مساعدتي مشكورا...

#2

السلام عليكم ,,

هناك نقطتين يجب الانتباه لهما في برنامجك ,,

النقطة الأولى, هي كيفية معرفة نوع الحقول في الجداول :

يجب أن يكون لديك معلومات عن أنواع الحقول, و لكن كيف يتم ذلك ؟

كما تعرف أن أي جدول سيحتوي على سجلات, و كل سجل يحتوي على حقول, عند إنشاء أي جدول أول شيء يجب وضعه في الملف هو نوع البيانات المستخدمة, كفكرة مبدئية فقط يمكنك أن يكون الـ header الخاص بلمف الجدول يحتوي على التالي :

Number of fields :
	field_1_type
	field_2_type
	field_3_type
	field_n_type

يمكن أن يكون أول عنصر هو عدد الحقول, لأن عدد الحقول يمكن أن يختلف من جدول إلى آخر, بعد ذلك تقوم بقراءة أنواع الحقول بعد أن عرفت عددها, نوع الحقل يمكن أن من char على سبيل المثال, و كل نوع يمثل بعدد, فلو قرأ البرنامج نوع الحقل الأول و وجد العدد (4) على سبيل المثال فيجب أن يعامله على أنه int, طبعاً هذا يعتمد على تصميمك للبرنامج و يجب أن تكون الأعداد متفق عليها عند عملية القراءة و الكتابة.

النقطة الثانية هي طول الحقول :

كما تعرف أن أنواع البيانات في ++C تملك أطوال ثابتة كـ int أو double و هذه لا مشكلة فيها, المشكلة تظهر عند التعامل مع الـ string, حسب برنامجك فإن طول النصوص ليس محدداً, بالتالي كيف يمكن معرفة طول النص ؟

إحدى الطرق, أن برنامجك عند كتابة النص, يقوم بكتابة طوله قبله, يمكن أن تستخدم int على سبيل المثال قبل كتابة النص للملف,

فإذا عرفت أن الحقل من نوع string ستقوم بقراءة int يمثل طول النص, بعد ذلك تقوم بقراءة النص بعد أن عرفت طوله, و بالتالي يكون طول حقل النص 4 + الطول الذي حصلت عليه من الأربع bytes التي ذكرناها سابقاً,

هذا ما لدي حالياً إذا كان لديك استفسار فلا تتردد,

تحياتي ,,

#3

اخي خالد .. يعطيك العافيه

وعندي استفسار ..

كيف انشئ مصفوفه من بعدين تختلف انواع ألأعمده فيها باختلاف الاعمده في الجدول ؟؟

يعني مثل المثال المرفق .. العمود الأول ID من نوع int والثاني Name من نوع string .. وهكذا لكي أخزن المعلومات فيها ..

تحياتي ..,

#4

السلام عليكم ,,

اقتباس
كيف انشئ مصفوفه من بعدين تختلف انواع ألأعمده فيها باختلاف الاعمده في الجدول ؟؟

لاحظ أخي العزيز أن هذه العملية ليست بالبساطة المتوقعة, لأن أنواع البيانات المطلوبة سيتم معرفتها وقت التشغيل و ليس وقت التصميم(كتابة الكود), الحقيقة لا تحضرني فكرة حالياً و لكن أتوقع الطريقة التي اقترحتها ليست بالسهلة لتطبيقها,

أعتقد أن عملية تمثيل كل عمود بمصفوفة أي أن عدة المصفوفات ستحمل الأعمدة و لكن هذا الشيء لن يلاحظه المستخدم, فأنت ستقوم بأخذ الحقول المطلوبة من الأعمدة للحصول على السجلات,

باختصار, عملية التخزين ستتم على مستوى الأعمدة و لكن عملية استرجاع البيانات(مهمة البرنامج نفسه) هي تكوين السجلات من هذه الأعمدة..

هذا بشكل أولي, الصراحة لم أفكر كثيراً في الموضوع, سأحاول أن أعطيك رداً مفصلاً أكثر عما قريب ,,

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 9 يناير 2008 في 23:07

#5

جزاك الله خيرا .... وانا في انتظار ردك

انا ما بدأت في المشروع الى الآن والسبب هو عدم وجود فكره أو خوارزم أستطيع البدء به ..

تحياتي لك ..,

#6

السلام عليكم ورحمة الله وبركاته...

أشكرك استاذي :Khaled.Alshaya على التوضيح الرائع..

أخي وسع صدركـ

اقتباس
كيف انشئ مصفوفه من بعدين تختلف انواع ألأعمده فيها باختلاف الاعمده في الجدول ؟؟

كانت هذه الطريقه في بالي لكن لم أعرف كيف أنفذها....!

لكن لها العباقره هنا....

===========================

فكرتي بإختصار

نعرف مصفوفة مؤشره من النوع void حجمها بعدد الأعمده.....

بعد ذلك نقوم بإنشاء (مصفوفه ديناميكيه)للحقل الأول بعدد السجلات(الصفوف) ، طبعاً بعد معرفة نوعه....

ثم نقوم بعملية قسر للعنصر الأول من مصفوفة المتغيرات void...

لنجعله يؤشر على بيانات من نوع الحقل الأول....

ثم نقوم بتهيئته ليشير إلى المصفوفه التي أنشأناها....

==========================

لتوضيح كلامي ،في المثال الوارد في السؤال:

ننشئ مصفوفة مؤشرات من النوع void حجمها 3

نقوم بقسر العنصر الأول ليشير إلى مصفوفة من النوع int

والعنصر الثاني ليشير إلى مصفوفة من النوع string

و العنصر الثالث ليشير إلى مصفوفة من النوع int

==========================

أتمنى أن تكون فكرتي صحيحة...

أعرف أنها صعبة التطبيق...

وسيلزم علينا حذف مصفوفات المتغيرات قبل حذفها....

إلى آخره من المشاكل التي ربما تواجهنا...

لذلك أتمنى أن يكون هناك حل أسهل من هذا...

دمتم في رعاية الله،،،،

موقع كلية الحاسب الآلي ونظم المعلومات.

WWW.UQUCS.COM

#7

بارك الله فيك أخي العواجي ,,

كلام أخي العواجي صحيح, و لكن هناك مشكلة بسيطة عندما يصبح البرنامج معتمداً,

المشكلة أن البرنامج لن يحمل قاعدة البيانات بشكل كامل إلى الذاكرة, هناك طرق كثيرة لحل هذه المشكلة و لكن ليس لدي الوقت حالياً للأسف :(

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 11 يناير 2008 في 12:41

#8

أخي العواجي .. فهمت فكرتك .. وسأحاول الحل بها الى ان أجد طريقه أسهل في الحل ..

وأشكر لك التوضيح .. وما قصرت ..

أخي خالد ..

أحد الأشخاص أقترح الحل باستخدام لوب وحفظ المعلومات مباشرة في الملف .. بدون انشاء مصفوفة من بعدين

واللوب هذي تكون في البرنامج الثاني المخصص لادراج البيانات ..

ربما الخيط هذا يقودك الى فكره مناسبة .. :)

دمتم في حفظ الله جميعا ..,

#9

السلام عليكم ورحمة الله

جزا الله خيرا كل من رد أو شارك ....

وأبشركم ياإخوان انتهيت من المشروع على أتم وجه وباقي التسليم فقط وعسى الله يكتب لنا الدرجة الممتازة....

أخونا خالد جزاك الله خير نصيحتك أخذتها بعين الاعتبار وأفادتني كثير ... لكن طول الحقول : لم أفهم ماهي الفائدة من معرفته؟؟

أهلا بأخينا العواجي ..مشاء الله عليك بكل منتدى ترد علي بيض الله وجهك..لكن ممكن توضح كيف نتعامل مع مصفوفة من نوع void للإدخال والأسناد وغيره؟؟

#10

لكن يا إخوان واجهتني مشكلة مع تنظيم البيانات في الملف حاليا أستعمل t\ لكن غير عملي إذا كان النص طويلا ...

فهل من فكرة؟؟وجزاكم الله خيرا...

#11

السلام عليكم ورحمة الله وبركاته...

اقتباس
..لكن ممكن توضح كيف نتعامل مع مصفوفة من نوع void للإدخال والأسناد وغيره؟؟

لا أعرف هذا ...!

ولم أحاول تطبيقه....

لكن الحمد لله أنه ممكن كما قال ذلك الأستاذ خالد...

إذا حصلت وقت بعد الاختبارات أحاول بمشيئة الله...

وإن كنت أتمنى أن يقوم بذلك أحد الأساتذة هنا...

بهذه المناسبة أقترح عليكم - اساتذتي - موضوع عن void ومعناه....

اقتباس
وأبشركم ياإخوان انتهيت من المشروع على أتم وجه وباقي التسليم فقط

الحمد لله...

أتمنى أن تضعه هنا أو هناك مع الشرح لتعم الفائدة...

دمتم في رعاية الله،،،

موقع كلية الحاسب الآلي ونظم المعلومات.

WWW.UQUCS.COM

#12
اقتباس
لكن ممكن توضح كيف نتعامل مع مصفوفة من نوع void للإدخال والأسناد وغيره؟؟

استخدمتها وضبطت معي .. انت ما تسند لها قيمه عدديه أو حرفيه ولكن تسند لها مؤشر إلى أي نوع ..

مثلا ..

void **ptr;
ptr = new void * [2];
ptr [0] = new int [5];
ptr [1] = new char [5];

اتمنى اني أكون قدرت أوصل المعلومه .. :)

اقتباس
يا إخوان واجهتني مشكلة مع تنظيم البيانات في الملف حاليا أستعمل t\

استعمل setw ;)

#13

جزاك الله خير أخونا العواجي

وأضم صوتي لصوتك....

وسأرفق المشروع بدون الكود لأن الكود لازم اسلمه أولا وآخذ الدرجة عليه ثم سأرفقه بإذن الله...

وأتمنى منك أخي العواجي والإخوة الآخرين تجربت المشروع ولاتبخلون علينا برأيكم..

الأخ وسع صدرك..

نعم أخي طريقتك صحيحة لكن كيف أستعمل هذه المؤشرات مع cin و cout كيف أسند لها قيم ...

أما بالنسبة أخي لـsetw لا تحل المشكلة كاملة ...

أنا سمعت إنه هناك left و right لتنظيم الملفات لكن لا أعرف كيفيتها؟؟

وجزاك الله كل خير ...

MyPr.zip

#14

السلام عليكم ,,

مصفوفات void تكلم عنها الأخ HGB في المواضيع المثبتة حول المؤشرات,

و لكن سأتكلم بشكل مبسط حول هذا النوع, رغم أني لن أتكلم عن void خصوصاً, لأنه عبارة عن شكل آخر للمؤشرات, و لكني سأعرض بعض الطرق للتحويل بين المؤشرات و التي ستفتح لك المجال, لأنه في الحقيقة لا يوجد أنواع مختلفة من المؤشرات ! و لكنه نوع واحد!

الآن لو أن لديك مصفوفة مكونة من ألف عنصر أو عنصرين فقط! هل سيختلف حجم المؤشر ؟ أو أن لديك ألف عنصر من النوع char أو ألف عنصر من النوع int! هل سيختلف حجم المؤشر ؟

الإجابة الصحيحة هي لا! بكل بساطة لأن المؤشر لا يحمل أي معلومات عن المصفوفة إلا عنوان أول عنصر فيها فقط!

بالتالي عرفنا أن المؤشرات تشبه أبواب البيوت, لأنه عن طريقها يمكنك الدخول و لكنها لا تمثل المعلومات المخزنة أصلاً!

إلى هنا أعتقد أننا اكتفينا من النظري :lol: و ربما تكون تعرف هذه المعلومات من قبل و لكنها لإنعاش الذاكرة ليس أكثر!

الآن تصور أننا عرفنا متغير من النوع int كالتالي :

int x;

أكيد أنك تعرف أن النوع int حجمه 4 bytes ! و لكن أليست الـ 4 bytes في حد ذاتها مصفوفة أصلاً مكونة من 4 عناصر كل عنصر عبارة عن byte! جميل جداً !!!

هنا يبرز دور المؤشرات في التعامل مع هذه الحالات!

كل ما علينا هو أن نشير إلى عنوان x بمؤشر آخر من نوع char لنحصل على مصفوفة مكونة من 4 عناصر!

كل ما علينا القيام به هو استعمال الـ casting كالتالي :

char* p = reinterpret_cast<char*>(&x);

في السطر الثاني عرفنا مؤشر من نوع char يشير إلى عنوان x و لتسمح لنا ++C يجب استخدام معامل "إعادة تفسير العنوان",

هذا لن يتضح إلا بالمثال, في المثال التالي سنقوم بكتابة struct إلى ملف binary مباشرة دون كتابة كل عنصر في الـ struct على حدة :

struct x{
	int i,n;
	char[4] y;
}

x StrucX;
ofstream f;

قمنا بتعريف ما يلزم في الأعلى, و نصل الآن إلى عملية الكتابة نفسها! كما تعلم أن الدالة write تستقبل مؤشر من نوع char و بالتالي لا يمكننا وضع عنوان StructX مباشرة للدالة, لذلك سنقوم بإعادة تفسير عنوان StructX من جديد! :

f.write( reinterpret_cast<char*>(&StructX), sizeof(StructX) );

هل فهمت الفكرة! هذه هي بكل بساطة, يمكنك استخدام reinterpret_cast مع المؤشرات من أي نوع سواء void أو غيره!

إلى هنا نصل إلى السؤال الأخير, إذا ما الفرق بين أنوع المؤشرات ؟!

الفرق يكمن في تعامل المترجم معها لا أكثر! و هذا يسمى بالـ pointer arithmetic , فلو أخذنا المثال التالي :

char* x;
int * y;

x++;
y++;

عندما قمنا بالزيادة على المؤشرين, فإن حجم الزيادة يختلف حسب نوع المؤشر لا اكثر! في حالة x yحرك بمقدار byte واحد, بينما y تحركت 4 bytes !!

هذا كل ما لدي حالياً, أتمنى أن تجد الفائدة فيه, و أنا جاهز للأسئلة :rolleyes:

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 13 يناير 2008 في 14:52

#15

جزاك الله خير أخي خالد ...

بالنسبة للمؤشرات أفهمها فهم جيد ولله الحمد ..وأكثر شيئ وضحها لي دالة write في ملفات binary ....التي تفضلت بذكرها ...حيث أن الدالة تعلمك أن المؤشر لايحتوي إلا على عنوان فقط ... وأنا أشبهه بـ(اختصارات البرامج على سطح المكتب)..

لكن المشكلة هنا:

int a;
string b;
char *pt[2];
pt[0]=reinterpret_cast<char*>(&a);
pt[1]=reinterpret_cast<char*>(&b);

المشكلة كيف أستخدم pt في الإسناد إلى المتغيرين مثل:

pt[0]=12123;
pt[1]="ahemd";
#16

ممكن أخي خالد تجرب مشروعي وتعطينا رأيك لو تكرمت.....؟

#17

السلام عليكم ,,

عملية تعديل قيم المتغيرات عن طريق مؤشرات من نوع آخر, للأسف ليست بتلك البساطة المتوقعة, هناك الكثير من الأمور التي يجب أخذها في الحسبان,

هذا المقال من codeguru يعتبر بداية جيدة لتوضيح أكبر مشكلة يمكن تواجهها, و هي كيفية تمثيل الأعداد في الذاكرة, المقال بسيط و به الكثير من المعلومات المفيدة.

War of the Worlds: Endianness

بالنسبة لمثالك الذي وضعته,

p[0]

سوف تشير إلى البايت الأول فقط و أقصى قيمة يستطيع حملها بايت واحد هي 255, لأن الـ int مكون من 4 bytes , لتعرف ماذا أقصد بأول بايت يجب عليك قراءة المقالة أولاً..

بالنسبة للعملية الثانية, فإنك عندما قمت باستخدام :

p[1]

فأنت قمت بتفسير عنوان الـ string على أنه *char و لكن هذا سيسبب لك مشاكل لا أول لها من آخر, لأن كائن النص يحتوي على دوال و له طريقة خاصة في حجز الذاكرة, و ليس مجموعة من الـ bytes المتجاورة في الذاكرة,,

بالنسبة للمشروع, فلامانع لدي و خصوصاً إذا كنت تستطيع وضعه في المنتدى لكي نستفيد منه جميعاً (إذا كان موعد المشروع قد انتهى)

تحياتي ,,

#18

وعليكم السلام....

للأسف أخي الكريم لغتي الإنجليزية ضعيفة جدا....لكن فهمت بعض الجمل والصور وضحت لي أكثر...

والأمر فعلا ليس بهذه السهولة...

لكن كيف يمكن ننشيء مصفوفة مؤشرات كل مؤشر يحمل عنوان متغير مختلف عن الآخر يهني int و double و string وغيرها

ثم عند الإسناد لهذه المتغيرات : بدلا من أن نستدعي كل متغير ...نستدعي مصفوفة المؤشرات ونجعل عملية الإسناد لكل متغير عبر المؤشر الخاص به...

يعني مثل مثالي السابق (مصفوفة مؤشرات char )....

**أما المشروع فقد أرفقته لكن كبرنامج ولم أرفق الكود (لأنني لم أسلم المشروع إلى الدكتور فإذا سلمت المشروع وأخذت عليه الدرجة سأرفق الكود بإذن الله )

وجزاك الله خيرا...

MyPr.zip

#19

السلام عليكم ,,

اقتباس
ثم عند الإسناد لهذه المتغيرات : بدلا من أن نستدعي كل متغير ...نستدعي مصفوفة المؤشرات ونجعل عملية الإسناد لكل متغير عبر المؤشر الخاص به...

كما قلت لك سابقاً هذا ممكن عن طريق الـ reinterpret_cast , و لكنه ليس بالبساطة المتوقعة, لأن كل ما يقوم به هذا الـ cast هو إعادة تفسير العنوان, و يترك باقي التفاصيل عليك, فهو لا يفرق بين أنواع بسيطة أو struct أو class أو غيره ,,

تحياتي ,,

#20

السلام عليكم

أخي خالد والعواجي وجميع الإخوان

هذا المشروع كامل مع الكود أرجوا أن تبدوا ملاحظاتكم تكرما وتفضلا منكم..

والمشروع باختصار عبارة عن ثلاثة برامج:

::شرح البرنامج::

البرنامج الأول Create تعطيه أولا عدد الأعمدة ثم تعطيه اسم كل عمود ونوعه ثم تعطيه اسم الملف الخاص بك

ثم تعطيه كم تريد من رقم بعد الفاصلة بالنسبة لـreal numbers.

البرنامج الثاني Insert تدخل بينات كل صف .

البرنامج الثالث Select أول إذا كنت تريد عرض المعلومات أدخل v لعرض الملف كاملا أو c لمتابعة البحث

ثم يعيطيك خيارات البحث (في أي عمود تريد)ثم تعطيه كلمة البحث.

بالنسبة للبرنامج الثاني والثالث لابد تكتب بعد أمر التشغيل اسم الملف الخاص بك الذي أعطيته للبرنامج الأول

بدون ملحق الملف اللي هو بعد '.'

جزاكم الله خير........ولا تبخلون علينا برأيكم..

finalProject3.zip

#21

السلام عليكم ,,

للأسف أخي العزيز, ليس لدي مترجم حالياً :(

عند أول فرصة سأرجع إلى موضوعك, و سأرى الكود,

و عذراً على التأخير,

تحياتي ,,

#22

بانتظارك أخي الكريم

والملف أرفقت معه التطبيق بعد الترجمة

يعني يطبق على طول بدون ترجمة للكود

هذا الموضوع مغلق.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…