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

الوصول لعناصر basic_streambuf المحميه

بدأه C++er في 12 مايو 2010 · 2 رد · 263 مشاهدة · في ارشيف قسم C/C++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

اقوم بعمل overload للمعاملين operator>> و operator<< للنوع basic_istream و basic_ostream لدعم مكتبة iostream مع فئات مكتبتى StrLib.

عملية اعادة تعريف insertion operator امرها سهل و قد انتهيت منها منذ فتره طويله اما الصعبه فهى استخراج النص من الـ stream بأقل قدر ممكن العمليات و ايضا من استهلاك الذاكره، عموما بعد البحث و الإطلاع على كود مكتبة iostream و string فهمت بعض الأمور.

الفئه istream تستخدم الفئه basic_streambuf كمخزن مؤقت للقيمه المدخله لـ stdin و عندما تتم القراءة من الفئه يتم نسخ محتويات الـ buffer إلى داخل المتغير، بالنسبه للفئه string (او لأكون دقيق basic_string) فإنه عند القراءة فإنه يتم حذف محتويات الفئه بأكملها و يتم اضافة محتويات الـ buffer حرف حرف حتى يتم الإنتهاء من النسخ.

فى حالتى هذه العمليه ستكون مكلفه جدا لإنى سأضطر للنسخ فى متغير char* مؤقت و من ثم انسخ محتوياته داخل المخزن الداخلى لدى و ذلك لأن الـ basic_streambuf لا تدعم الوصول لعناصرها إلا إذا كنت ترثها، لذا فقد فكرت فى النسخ مباشرة من نسخة basic_streambuf المستخدمه من قبل الكائن cin.

فى البدايه سأقوم بإستدعاء الداله

cin.rdbuf()->sgetc()

و ذلك حتى يقوم المستخدم بإدخال النص الذى يريد و الداله نفسها ستعيد لى اول حرف تم ادخاله من المستخدم، الأن المفترض ان اصل بطريقه ما للـ buffer الداخلى و الذى مسبقا انا اعرف مساحته من خلال استدعائى للداله

cin.rdbuf()->in_avail()

المساحه العائده هى عدد الحروف التى تم قرائتها بالإضافة إلى الـ null terminator.

توجد الداله gptr() و هى protected دخل الـ streambuf، عندما رأيت هذه الداله ابشرت لإنى اعتقدت انى قد استطيع ان ارث الفئه basic_streambuf و بعد هذا اضع داخل نسختى ما اريد من دوال و بعدها اقوم بتحديد لـ istream ان نسخة الـ buffer ألأتى تتعامل معها هى نسختى و لكن عند محاولة تطبيق هذه الطريقه ظهرت لى اخطاء عديده و صراحه لقد وصل عقلى لمرحلة الإنغلاق لإنى اعمل عليها من اول اليوم فهل من معين.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 12 مايو 2010 في 01:18

1

مدونتي: C++ Tips and Tricks

#2

انا الأن غاضب جدا :mad: :mad: :mad:

قمت بوراثة الفئه streambuf و ذلك حتى استطيع للوصول للداله gptr

class internal_streambuf : public streambuf
{
public:
	internal_streambuf() : streambuf()
	{}

	char* internal_buffer()
	{ return gptr(); }

};

بعد ذلك داله الـ extraction اصبحت كالتالى:

istream& operator>>(istream& is, StringA& str)
{
	internal_streambuf mybuf;

	streambuf* old_buf = is.rdbuf(&mybuf);

	is.rdbuf()->sgetc();

	if (mybuf.in_avail() != 0)
		str = mybuf.internal_buffer();

	is.rdbuf( old_buf );

	return is;
}

هذا ليس الشكل النهائى للداله و لكن كمرحله مبدئيه المفترض انها تعمل بشكل مماثل لأى نوع نصى اخر و لكنها لم تعمل و السبب أن الـ buffer الدخلى للفئه internal_streambuf فارغ و بالتالى لا يمكن الإضافة لمخزن فارغ و بهذا تفشل عملية الـ extraction.

السؤال الأن كيف اقوم بالله عليكم بعمل initialize لهذا الـ buffer ؟؟؟

مدونتي: C++ Tips and Tricks

#3

إذا لم يعلم حل لها فلا بأس،

على الأقل هل يستطيع احد ان يعلمنى كيف تقوم الفئه basic_string بعمل intialize للفئه streambuf داخل المعامل operator>> فى التعريف التالى:

template<class _Elem, class _Traits, class _Alloc> 
inline basic_istream<_Elem, _Traits>& operator>>(basic_istream<_Elem, _Traits>& _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str);

إذا كنت تستخدم فيجوال سى ستجد تعريفها داخل الملف string و إذا كنت تستخدم الإصدار 2008 فستجدها فى السطر 511 بالتحديد.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

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