Professional Documents
Culture Documents
الـمحتويات
Contents
مركز املكتبة هو عدة فئات للحاويات وعائلة من الخوارزميات الشاملة تتيح لنا كتابة برامج مخترصة وفعالة.
تهتم املكتبة بتفاصيل إدارتها – ﻻسيما العناية بإدارة الذاكرة – ، •
بحيث تسمح لربامجنا أن تهتم بشأن املشكالت الفعلية اليت نحتاج إلى حلها. •
لقد قدمنا نوع حاوية املتجه فيي الفصل الثالث ؛ في الفصل التاسع سنتعرف على تلك الحاوية أكرث ، •
وسنغطي أنواع حاويات متسلسلة أخرى أيضاً ،إضافة إلى تغطية عمليات أكرث يوفرها نوع السلسلة. •
بإمكاننا أن نعترب السلسلة نوع حاوية خاص يحوي أحرفاً فقط ،ويدعم عدة عمليات للحاويات وليس كلها. •
أما في الفصل العارش فسنقدم الخوارزميات الشاملة اليت تعمل في العادة على مجموعة عنارص في الحاوية •
املتسلسلة أو أي تسلسل آخر.
تقدم مكتبة الخوارزميات هذه تطبيقات فعالة لعدة خوارزميات كالسيكية كالفرز والبحث ومهام أخرى. •
أوجـد اليت تبحث عن
فمثالً ،ت ُّقدم خوارزمية نسخ ،اليت تنسخ العنارص من تسلسل ﻵخر ،وخوارزمية ِ •
عنرص معني … إلخ.
هذه الخوارزميات تعترب شاملة من وجهني ، •
اﻷول :أنه يمكن تطبيقها على تسلسالت من أنواع مختلفة ، •
والثاني :أن تلك التسلسالت قد تحتوي على عنارص من معظم اﻷنواع. •
كما توفر املكتبة عدة حاويات تجميعية وستكون موضوع الفصل الحادي عرش .
الوصول إلى العنارص في الحاويات التجميعية يتم بواسطة مفتاح. •
تلك الحاويات تتشارك مع الحاويات املتسلسلة في عمليات عدة وتنفرد بعمليات خاصة بها أيضاً. •
نختم هذا الجزء بالفصل الثاني عرش الذي يبحث في أقسام اللغة واملكتبة الخاصة بإدارة الذاكرة الحيوية.
يغطي هذا الفصل أحد أهم فئات املكتبة الجديدة وهي :إصدارات املؤرشات الذكية القياسية. •
هذه اﻹصدارات تمكننا من عمل أكواد أكرث قوة وصالبة عند استخدام الذاكرة الحيوية. •
في نهاية ذلك الفصل سنقدم مثاال ً موسعاً ،نستخدم فيه أقسام املكتبة اليت قُدمت في الجزء الثاني. •
الفصــــــــــل . 8مكتبــــــــــة املدخــــــــــالت واملخرجــــــــــات
Chapter 8. The IO Library
الـمحتويات
Contents
أنواع املدخالت واملخرجات والكائنات اليت استخدمناها حىت اآلن تتعامل مع بيانات األحرف .char
افرتاضياً ،يتم توصيل هذه الكائنات بنافذة وحدة التحكم الخاصة باملستخدم .وبالطبع ، •
لن تقترص الربامج الحقيقية على إجراء عمليات املدخالت واملخرجات على نافذة وحدة التحكم أو منها فقط ؛ •
بل ستحتاج في الغالب إلى قراءة ملفات مسماة أو الكتابة عليها. •
عالوة على ذلك ،قد يكون من املالئم استخدام عمليات مدخالت /مخرجات ملعالجة األحرف في سلسلة. •
دعما كبريًا لألحرف.
ً أيضا إلى قراءة وكتابة لغات تتطلب
• قد تضطر التطبيقات ً
تعرف املكتبة مجموعة أنواع مدخالت ومخرجات
لدعم هذه األنواع املختلفة من معالجة املدخالت واملخرجات ّ ،
إضافة لتلك اليت استخدمناها بالفعل.
• يتم تعريف هذه األنواع ،املدرجة في الجدول ، 8.1في ثالثة عناوين منفصلة:
يعرف العنوان iostreamاألنواع األساسية املستخدمة للقراءة من القناة والكتابة إليها ،
ّ •
ويعرف العنوان fstreamاألنواع املستخدمة لقراءة امللفات املسماة وكتابتها ،
ّ •
ويعرف العنوان sstreamاألنواع املستخدمة لقراءة وكتابة سالسل في الذاكرة.
ّ •
من ناحية املفاهيم ،ال يؤثر نوع الجهاز وال حجم الحرف على عمليات املدخالت واملخرجات اليت نريد تنفيذها.
فمثالً ،قد نستخدم >> لقراءة بيانات بغض النظر إن كانت من نافذة وحدة تحكم أو ملف قرص أو سلسلة. •
وباملثل ،سنستخدم هذا العامل بغض النظر إن كانت األحرف تتناسب مع حرف أو تتطلب أحرفاً عريضة. •
تتيح لنا املكتبة تجاهل االختالفات بني هذه األنواع املختلفة من القنوات باستخدام الوراثة.
وكما هو حال القوالب ،يمكننا استخدام فئات مرتبطة بالوراثة دون حاجة لفهم تفاصيل كيفية عمل الوراثة. •
وسنغطي كيفية دعم يس ++للوراثة في الفصل 15والفقرة .18.3 •
ولكن باختصار ،تتيح لنا الوراثة أن نقول إن فئة معينة ترث من فئة أخرى. •
وفي العادة ،يمكننا استخدام كائن من فئة موروثة كأنه كائن من نفس نوع الفئة اليت ترث منها. •
فالنوعان ( ifstreamقناة مدخالت امللفات) و ( istringstreamقناة مدخالت السلسلة) يرثان من •
قناة املدخالت .istream
بالتالي ،يمكننا استخدام كائنات قناة مدخالت امللفات أو قناة مدخالت السلسلة مثل كائنات قناة املدخالت. •
كما يمكننا استخدام كائنات من هذه األنواع بنفس الطرق اليت استخدمنا بها .cin •
فعلى سبيل املثال ،يمكننا استدعاء getlineعلى كائن قناة مدخالت امللفات أو قناة مدخالت السلسلة ، •
ويمكننا استخدام >> لقراءة البيانات من قناة مدخالت امللفات أو قناة مدخالت السلسلة.
وباملثل ،فإن أنواع ofstreamقناة مخرجات امللفات و ostringstreamقناة مخرجات السلسلة ترث •
من قناة املخرجات .ostream
ولذا ،يمكننا استخدام كائنات هذه األنواع بنفس الطرق اليت استخدمنا بها .cout •
ملحوظة
كل ما نغطيه فيما تبقى من هذا القسم ينطبق بتسا ٍو على القنوات العادية وقنوات امللفات والسلسلة وعلى
إصدارات القناة ذات األحرف أو األحرف العريضة.
كما رأينا في الفقرة ، 7.1.3ال يمكننا النسخ أو التعيني على كائنات أنواع املدخالت أو املخرجات :
وألنه من غري املمكن نسخ أنواع املدخالت واملخرجات ،فال يمكننا الحصول على معلمة أو نوع إعادة يمثل أحد
أنواع القناة.
• في العادة تقوم الدوال اليت تعالج عمليات املدخالت واملخرجات بتمرير أو إعادة القناة عرب املراجع.
فقراءة أو كتابة كائن املدخالت واملخرجات سيغري من حالته ،ولذلك يجب أال يكون املرجع ثابتاً. •
الحقيقة أن األخطاء يمكن أن تحدث .فبعضها قابل لالسرتداد ؛ وأخرى تحدث في عمق النظام وتخرج عن إمكانيات
الربنامج من أجل تصحيحها.
تعرف فئات املدخالت واملخرجات الدوال والعالمات ،املدرجة في الجدول ، 8.2
ّ •
واليت تتيح لنا الوصول إلى حالة القناة والتعامل معها. •
;int ival
;cin >> ival
إذا أدخلنا Booإلى تلك املدخالت القياسية ،فستفشل القراءة .ﻷن عامل املدخالت قد توقع قراءة ، int
لكنه حصل على الحرف Bبدال ً من ذلك .ونتيجة لذلك ، •
سيتم وضع cinفي حالة خطأ .وباملثل ،فإن cinفي حالة خطأ لو صادفنا نهاية ملف. •
بمجرد حدوث خطأ ،ستفشل عمليات املدخالت /املخرجات الالحقة على تلك القناة. •
ومن ثم ،ال يمكننا القراءة من القناة أو الكتابة عليها إال عندما تكون في حالة عدم الخطأ. •
وألن أي قناة قد تكون في حالة خطأ ،ينبغي على الكود عاد ًة فحص كون القناة صالحة قبل محاولة •
استخدامها.
وأسهل طريقة لتحديد حالة كائن القناة هي استخدام ذلك الكائن كرشط: •
يتحقق رشط طالـما_ whileمن حالة القناة املعادة من تعبري >>. •
فإن نجحت عملية املدخالت هذه ،ستبقى الحالة صالحة وينجح الرشط. •
اإلصدار clearالذي يأخذ وسيطة يتوقع قيمة iostateتمثل الحالة الجديدة للقناة. •
إليقاف تشغيل رشط واحد ،نستخدم العضو rdstateوعوامل البتات إلنتاج الحالة الجديدة املطلوبة. •
فمثالً ،يؤدي ما يلي إلى إيقاف تشغيل failbitو badbitولكنه يرتك eofbitكما هو : •
// turns off failbit and badbit but all other bits unchanged
;)cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit
التمرين :8.1
-اكتب دالة تأخذ وتعيد مرجع قناة املدخالت &.
-يجب أن تقرأ الدالة القناة حىت تصادف نهاية ملف.
-يجب أن تطبع الدالة ما تقرأه على املخرجات القياسية.
-أعد تعيني القناة بحيث تكون صالحة قبل إعادة القناة.
التمرين :8.2
-اخترب دالتك من خالل استدعاءها ،وتمرير cinكوسيطة.
التمرين :8.3
ما الذي يتسبب في إنهاء طالـما_ التالية؟
while (cin >> i) /*...*/
تدير كل قناة مخرجات مخز ًنا مؤق ًتا تستخدمه لتحتفظ بالبيانات اليت يقرأها الربنامج ويكتبها.
فعلى سبيل املثال ،عند تنفيذ الكود التالي
قد تتم طباعة السلسلة الحرفية على الفور ،أو قد يتم تخزين البيانات في مخزن مؤقت لطباعتها الح ًقا. •
يسمح استخدام املخزن املؤقت للنظام بدمج عدة عمليات مخرجات من برنامجنا في كتابة واحدة على •
مستوى النظام.
ونظرًا ألن الكتابة على جهاز يمكن أن تستغرق وق ًتا طويالً ، •
فإن السماح للنظام بدمج عدة عمليات مخرجات في عملية كتابة واحدة قد يوفر تعزي ًزا مهماً لألداء. •
هناك عدة حاﻻت تؤدي إلى مسح املخزن املؤقت من -أي أن تتم كتابته على -جهاز أو ملف املخرجات الفعلي :
أن يكتمل الربنامج بشكل طبيعي .حيث يتم مسح كل مخازن املخرجات املؤقتة كجزء من العائد من .main •
في وقت غري محدد ،يمكن أن يمتلئ املخزن املؤقت ،وفي تلك الحالة سيتم مسحه قبل كتابة القيمة التالية. •
ويمكننا مسح املخزن املؤقت بشكل رصيح باستخدام معالج مثل . endl •
كما يمكننا استخدام املعالج unitbufلضبط حالة القناة الداخلية إلفراغ املخزن املؤقت بعد كل عملية •
مخرجات.
افرتاضياً ،يتم تعيني unitbufعلى ، cerrبحيث يتم مسح عمليات الكتابة إلى cerrعلى الفور. •
قد تكون قناة املخرجات مرتبطة بقناة أخرى. •
في تلك الحالة ،يتم مسح املخزن املؤقت للقناة املرتبطة كلما تمت قراءة القناة املرتبطة أو الكتابة عليها. •
افرتاضياً ،يتم ربط كل من cinو cerrبـ .coutومن ثم ،فإن أي قراءة من cinأو كتابة على cerr •
تمسح املخزن املؤقت في .cout
لقد استخدمت برامجنا بالفعل املعالج ، endlوالذي ينهي السطر الحالي ويمسح املخزن املؤقت.
هناك نوعان من املعالجات اﻷخرى املتشابهة flush :و .ends •
يفرغ flushالقناة لكنه لن يضيف أي أحرف إلى املخرجات ؛
ّ •
بينما تقوم endsبإدراج حرف فارغ في املخزن املؤقت ثم تمسحه : •
;cout << "hi!" << endl // writes hi and newline, then flushes buffer
;cout << "hi!" << flush // writes hi, then flushes buffer; adds no data
;cout << "hi!" << ends // writes hi and null, then flushes buffer
إذا أردنا التنظيف بعد كل عملية مخرجات ،فيمكننا استخدام املعالج .unitbuf
والذي يخرب القناة بالقيام بعملية مسح بعد كل كتابة الحقة. •
يستعيد املعالج nounitbufالقناة الستخدام قناة املخزن املؤقت العادي الذي يديره النظام: •
ال يتم مسح املخازن املؤقتة للمخرجات إذا انتهى الربنامج بشكل غري طبيعي. •
فعند تعطل أحد الربامج ، •
يحتمل أن تكون البيانات اليت كتبها الربنامج في مخزن مخرجات مؤقت بانتظار طباعتها. •
عند تصحيح أخطاء برنامج تعطل ، •
من الرضوري التأكد من مسح أي مخرجات يعتقد أنه كان ينبغي كتابتها. •
يتم إهدار ساعات ال حرص لها من وقت املربمج في التتبع عرب أكواد يبدو أنها لم يتم تنفيذها ؛ •
بينما هي في الواقع عدم مسح املخزن املؤقت وكانت املخرجات معلقة عند تعطل الربنامج. •
ملحوظة
ينبغي أن تربط األنظمة التفاعلية عادة قناة املدخالت بقناة املخرجات .فالقيام بذلك سيعين : •
أن أية مخرجات – قد تتضمن مطالبات للمستخدم – ستتم كتابتها قبل محاولة قراءة أية مدخالت. •
;)cin.tie(&cout // illustration only: library ties cin and cout for us
// old_tie points to stream (if any) currently tied to cin
ostream *old_tie = cin.tie(nullptr); // cin is no longer tied
// ties cin and cerr; not a good idea because cin should be tied to cout
;)cin.tie(&cerr // reading cin flushes cerr, not cout
cin.tie(old_tie); // reestablish normal tie between cin and cout
لربط قناة معينة بقناة مخرجات جديدة ،نقوم بتمرير مؤرش ربط إلى القناة الجديدة. •
فارغا.
ً لفك ربط القناة بالكامل ،نمرر مؤرشًا •
يمكننا ربط كل قناة بقناة واحد على األكرث في كل مرة .مع ذلك ، •
يمكن أن تربط قنوات متعددة نفسها بنفس قناة املخرجات. •
. 8٫2مدخــــــــــالت ومخرجــــــــــات الـملـفــــــــات
8.2. File Input and Output
عرف هذا الكود inكقناة مدخالت تمت تهيئتها على القراءة من ملف مسمى بواسطة وسيطة السلسلة
يُ ّ •
.ifile
يتم تعريف outكقناة مخرجات غري مرتبطة بعد بملف. •
باستخدام املعيار الجديد ،يمكن أن تكون أسماء امللفات إما سالسل مكتبة أو مصفوفات أحرف النمط .C •
كانت اإلصدارات السابقة من املكتبة تسمح فقط بمصفوفات أحرف النمط .C •
كما أرشنا في الفقرة ، 8.1يمكننا استخدام كائن من نوع موروث في أماكن يتوقع فيها كائن نوع أصلي.
• تعين هذه الحقيقة أنه يمكن استدعاء دوال تمت كتابتها ألخذ مرجع (أو مؤرش) ألحد أنواع قناة املدخالت
واملخرجات نيابة عن نوع قناة امللفات (أو sstreamقناة السلسلة) املقابلة.
• بمعىن ،إذا كانت لدينا دالة تأخذ مرجع قناة مخرجات & ،
فيمكننا استدعاء هذه الدالة بتمرير كائن قناة مخرجات امللفات ،وباملثل لـقناة املدخالت و قناة مدخالت •
امللفات لها
مثالً ،يمكننا استخدام الدوال قراءة وطباعة من فقرة 7.1.3للقراءة من ملفات مسماة والكتابة عليها. •
في هذا املثال ،سنفرتض أن أسماء ملفات املدخالت واملخرجات يتم تمريرها كوسيطات إلى : main •
وبرصف النظر عن استخدام ملفات مسماة ،فإن هذا الكود مطابق تقريبًا إلصدار برنامج اإلضافة السابق. •
الجزء املهم هو استدعاءات قراءة وطباعة. •
يمكننا تمرير كائناتنا قناة ملفات إلى هذه الدوال بالرغم من أن معلماتها يتم تعريفها كمراجع قناة مدخالت •
ومراجع قناة مخرجات ،على التوالي.
The open and close Members اﻷعضاء فتح_ وإغالق_
نعرف كائن قناة ملف فارغ ،يمكننا فيما بعد ربط هذا الكائن بملف عن طريق استدعاء :open
عندما ّ
إذا فشل استدعاء فتح_ ،يتم ضبط القناة على بت_فاشل .failbit •
ونظرًا الحتمال فشل اﻻستدعاء على املراد فتحه ،فمن األفضل عاد ًة التحقق من نجاح فتح_ : •
إن نجح فتح_ ،فإن الفتح يضبط حالة القناة بحيث تكون () goodقيمة صحيحة. •
فك ر في برنامج تأخذ دالته الرئيسية قائمة بملفات ينبغي معالجتها .فقد يحتوي برنامج كهذا على حلقة مثل :
ّ
ينئش كل تكرار كائن قناة مدخالت ملف جدي ًدا باسم inputويفتحه لقراءة امللف املحدد. •
كالعادة ،نتحقق من نجاح الفتح .فإن كان ناجحاً ، •
فإننا نمرر هذا امللف إلى دالة من شأنها قراءة املدخالت ومعالجتها. •
إن لم ينجح الفتح ،سنطبع رسالة خطأ ونستمر. •
ونظرًا ألن املدخالت محلية التعريف في حلقة ﻷجل_ ،يتم إنشاؤها وإتالفها مع كل تكرار. •
تلقائيا.
ً عندما يخرج كائن قناة امللفات من النطاق ،يتم إغالق امللف املرتبط به •
في التكرار التالي ،يتم إنشاء املدخالت من جديد. •
ملحوظة
تلقائيا.
ً عندما يتم تدمري كائن قناة ملفات ،يتم استدعاء إغالق_
التمرين :8.4
-اكتب دالة لفتح ملف للمدخالت وقراءة محتوياته في متجه من السالسل ،وتخزين كل سطر كعنرص منفصل في
املتجه.
التمرين :8.5
-أعد كتابة الربنامج السابق لتخزين كل كلمة في عنرص منفصل.
التمرين :8.6
-أعد كتابة برنامج متجر الكتب من الفقرة 7.1.1لقراءة معامالته من ملف.
-قم بتمرير اسم امللف كوسيطة إلى . main
تحتوي كل قناة على وضع ملف مرتبط يمثل كيفية استخدام امللف.
يرسد الجدول 8.4أوضاع امللفات ومعانيها.
يمكننا توفري وضع ملف عندما نفتح مل ًفا -إما عندما نستدعي فتح_ أو عندما نفتح ملفاً بشكل غري مبارش عند
تهيئة قناة على اسم ملف .األوضاع اليت يمكننا تعريفها تملك القيود التالية:
• ﻻ يسمح بالضبط على outإﻻ لكائن قناة مخرجات ملفات ofstreamأو قناة ملفات .fstream
ﻻ يسمح بالضبط على inإﻻ لكائن قناة مدخالت ملفات ifstreamأو قناة ملفات .fstream •
أيضا.
ﻻ يمكن الضبط على truncإﻻ عندما يتم تحديد ً out •
يمكن تعريف وضع appطاملا لم يتم تحديد .trunc •
دائما في وضع ، outحىت لو لم يتم تحديد outرصاحة.
ً إذا تم تعريف ، appفسيتم فتح امللف •
افرتاضياً ،يتم اقتطاع امللف املفتوح في وضع outحىت إن لم نحدد .trunc •
أيضا تحديد ، app
لالحتفاظ بمحتويات ملف مفتوح في وضع ، outفإما يجب علينا ً •
وفي هذه الحالة يمكننا الكتابة فقط إلى آخر امللف ، •
مفتوحا لكل من املدخالت واملخرجات.
ً أو يجب علينا أيضاً تحديد ، inوفي تلك الحالة يكون امللف •
(الفقرة 17.5.3تغطي استخدام نفس امللف للمدخالت واملخرجات). •
يمكن تحديد وضعي ateو binaryعلى أي نوع كائن قناة ملف مقرتناً مع أي أوضاع ملف أخرى. •
يحدد كل نوع قناة ملف وضع ملف افرتايض يتم استخدامه عندما ال نحدد وضعاً بطريقة أخرى.
فيتم فتح امللفات املرتبطة بـ قناة مدخالت ملفات في الوضع in؛ •
ويتم فتح امللفات املرتبطة بـ قناة مخرجات ملفات في الوضع out؛ •
وامللفات املرتبطة بـ قناة ملفات يتم فتحها بأوضاع inو .out •
افرتاضياً ،عندما نفتح قناة مخرجات ملف ، ofstreamيتم تجاهل محتويات امللف.
والطريقة الوحيدة ملنع قناة مخرجات ملف من إفراغ امللف املحدد هي تحديد وضع اﻹلحاق : app •
تحذير
الطريقة الوحيدة للحفاظ على بيانات موجودة في ملف مفتوح بواسطة قناة مخرجات ملفات هي تحديد
وضع اﻹلحاق appأو وضع املدخالت inبشكل رصيح.
قد يتغري وضع ملف لقناة معينة في كل مرة يتم فيها فتح امللف.
;ofstream out // no file mode is set
;)"out.open("scratchpad // mode implicitly out and trunc
;)(out.close // close out so we can use it for different file
;)out.open("precious", ofstream::app // mode is out and app
;)(out.close
أول استدعاء سيتم فتحه ال يحدد الوضع outبشكل رصيح ؛ سيتم الفتح ضمنياً في وضع .out •
وكالعادة ،يتضمن وضع outوضع اﻻقتطاع .trunc •
لذلك ،سيتم اقتطاع امللف املسمى scratchpadفي املجلد الحالي. •
عندما نفتح امللف املسمى ، preciousنطلب وضع اإللحاق. •
ستستمر أي بيانات في امللف ،وتتم جميع عمليات الكتابة في آخر امللف. •
ملحوظة
في أي وقت يتم استدعاء الفتح ،يتم ضبط وضع امللف ،سواء بشكل رصيح أو ضمين. •
وعندما ال يتم تحديد وضع ،يتم استخدام قيمة افرتاضية. •
التمرين :8.7
-قم بمراجعة برنامج متجر الكتب من القسم السابق لكتابة مخرجاته في ملف.
-قم بتمرير اسم هذا امللف كوسيطة ثانية إلى .main
التمرين :8.8
-قم بمراجعة الربنامج من التمرين السابق إللحاق مخرجاته بامللف املحدد.
-قم بتشغيل الربنامج على نفس ملف املخرجات مرتني على األقل لضمان االحتفاظ بالبيانات.
. 8٫1قنــــــــــوات الـسلــــــــــسلــــــــــة
8.3. string Streams
معرفة سلسلة
الجدول .8.5عمليات ّ
الحظ أنه على الرغم من أن قناة امللفات fstreamوقناة السلسلة sstreamيشرتكان في الواجهة مع •
قناة املدخالت واملخرجات ، iostreamإال أنهما ال يوجد بينهما عالقة متبادلة أخرى.
وتحديداً ،ال يمكننا استخدام openو closeعلى قناة السلسلة ، stringstream •
كما ال يمكننا استخدام strعلى قناة امللفات. •
غالبا ما يتم استخدام قناة مدخالت السلسلة عندما يكون لدينا بعض األعمال اليت يجب القيام بها على سطر كامل ،
ً
وأعمال أخرى تتعلق بكلمات فردية داخل السطر.
• كمثال ،افرتض أن لدينا مل ًفا يرسد أسماء األشخاص وأرقام هواتفهم املرتبطة.
رقما واح ًدا فقط ،بينما يمتلك آخرون عدة أرقام كهاتف املزنل وهاتف العمل ورقم
• يمتلك بعض األشخاص ً
الجوال وما إلى ذلك.
• قد يبدو ملف مدخالتنا كما يلي :
سيكون لكائنات من نوع PersonInfoعضو يمثل اسم الشخص ومتجه يحمل عد ًدا متغريًا من أرقام •
هواتفه املرتبطة.
سيقوم برنامجنا بقراءة ملف البيانات وإنشاء متجه لـ .PersonInfo •
سيتوافق كل عنرص في املتجه مع سجل واحد في امللف. •
وسنعالج املدخالت في حلقة تقرأ سجاًل ثم نستخرج االسم وأرقام الهواتف لكل شخص : •
;string line, word // will hold a line and word from input, respectively
vector<PersonInfo> people; // will hold all the records from input
)// read input line at time until cin hits end-of-file (or another error
{ ))while (getline(cin, line
; PersonInfo info // create an object to hold this record's data
;) istringstream record(line // bind record to the line we just read
; record >> info.name // read the name
) while (record >> word // read the phone numbers
;) info.phones.push_back(word // and store them
people.push_back(info); // append this record to people
}
التمرين :8.9
-استخدم الدالة اليت كتبتها للتمرين األول في الفقرة 8.1.2لطباعة محتويات كائن قناة مدخالت السلسلة.
التمرين :8.10
برنامجا لتخزين كل سطر من ملف في متجه <.>stringً -اكتب
-استخدم اآلن قناة مدخالت السلسلة لقراءة كل عنرص من املتجه لكلمة في وقت واحد.
التمرين :8.11
-حدد الربنامج في هذا القسم كائن قناة مدخالت السلسلة داخل حلقة whileالخارجية.
-ما هي التغيريات اليت ستحتاج إلى إجرائها إذا تم تعريف السجل خارج تلك الحلقة؟
-أعد كتابة الربنامج ،وانقل تعريف السجل إلى خارج ، while
-وانظر ما إذا كنت قد فكرت في جميع التغيريات املطلوبة.
التمرين :8.12
-ملاذا لم نستخدم مهيئات داخل الفئة في PersonInfo؟
تكون قناة مخرجات السلسلة مفيدة عندما نحتاج إلى زيادة مخرجاتنا قليالً كل مرة ولكن ال نريد طباعة املخرجات
حىت وقت الحق.
• مثالً ،قد نرغب في التحقق من صحة أرقام الهواتف اليت قرأناها في املثال السابق وإعادة تنسيقها.
• إذا كانت جميع األرقام صحيحة ،فنحن نريد طباعة ملف جديد يحتوي على األرقام اليت تمت إعادة
تنسيقها.
• إذا كان لدى أي شخص أي أرقام غري صالحة ،فلن نضعها في امللف الجديد.
بدال ً من ذلك ،سنكتب رسالة خطأ تحتوي على اسم الشخص وقائمة بأرقامه غري الصالحة. •
ونظرًا ألننا ال نريد تضمني أي بيانات لشخص لديه رقم غري صالح ، •
فال يمكننا طباعة مخرجات حىت نرى جميع أرقامهم ونتحقق من صحتها. •
ومع ذلك ،يمكننا "كتابة" املخرجات إلى قناة مخرجات السلسلة في الذاكرة : •
{ )for (const auto &entry : people // for each entry in people
ostringstream formatted, badNums; // objects created on each loop
for (const auto &nums : entry.phones) { // for each number
{ )) if (!valid(nums
; badNums << " " << nums // string in badNums
} else
formatted << " " << format(nums); // “writes” to formatted's string
}
))( if (badNums.str().empty // there were no bad numbers
" " << os << entry.name // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry.name
;<< " invalid number(s) " << badNums.str() << endl
}
في هذا الربنامج ،افرتضنا دالتني valid ،و ، formatللتحقق من صحة أرقام الهواتف وإعادة •
تنسيقها ،على التوالي.
الجزء املثري لالهتمام من الربنامج هو استخدام قنوات السلسلة لـ formattedو .badNums •
نستخدم عامل مخرجات عادي (<<) للكتابة على هذه الكائنات. •
لكن ،هذه "الكتابة" هي في الحقيقة معالجة سلسلة. •
إنها تضيف أحر ًفا إلى السالسل داخل formattedو ، badNumsعلى التوالي. •
التمرين :8.13
-أعد كتابة برنامج رقم الهاتف من هذا القسم للقراءة من ملف مسمى وليس من .cin
التمرين :8.14
-ملاذا تم الترصيح عن املدخالت واألرقام على أنها & const auto؟
ملخــــــــــص الفصــــــــــل
Chapter Summary
يستخدم يس ++فئات املكتبة للتعامل مع املدخالت واملخرجات املوجهة نحو القناة :
تتعامل فئات ( iostreamقناة املدخالت واملخرجات) مع املدخالت واملخرجات لوحدة التحكم •
تتعامل فئات ( fstreamقناة امللفات) مع املدخالت /املخرجات للملفات املسماة •
تقوم فئات ( Stringstreamقناة السلسلة) بمدخالت ومخرجات إلى سالسل في الذاكرة •
ترتبط فئات قناة امللفات و قناة السلسلة بالوراثة إلى فئات قناة املدخالت واملخرجات.
ترث فئات املدخالت من قناة املدخالت وفئات املخرجات من قناة املخرجات. •
أيض ا إجراء عمليات يمكن إجراؤها على كائن قناة املدخالت إما على قناة مدخالت ملفات أو
وبالتالي ،يمكن ً •
قناة مدخالت سلسلة.
وباملثل ينطبق اﻷمر نفسه بالنسبة لفئات املخرجات ،اليت ترث من قناة املخرجات. •
يحتفظ كل كائن مدخالت ومخرجات بمجموعة من الحاالت اليت تشري إلى ما إذا كان يمكن إجراء مدخالت أو
مخرجات من خالل هذا الكائن.
ٍ
عندئذ ستكون حالة الكائن في خطأ • ففي حالة مواجهة خطأ -مثل مصادفة نهاية ملف في قناة املدخالت -
بحيث ال يمكن إجراء أي مدخالت أخرى حىت يتم تصحيح الخطأ.
• توفر املكتبة مجموعة من الدوال لتعيني واختبار تلك الحاالت.
مصطلحــــــــــات معــــــــــرفة
Defined Terms
حالة الرشط :عالمات ودوال مرتبطة بتلك العالمات قابلة لالستخدام من قبل أي من فئات القناة اليت
condition state
تشري إلى ما إذا كانت قناة معينة قابلة لالستخدام.
وضع امللف :عالمات محددة بواسطة فئات قناة ملفات يتم تحديدها عند فتح ملف والتحكم في
file mode
كيفية استخدامه.