Dasturlash II


Laboratoriya ishi №:4 Buferlashtirilgan kiritish va chiqarish


Download 297.3 Kb.
bet6/13
Sana07.03.2023
Hajmi297.3 Kb.
#1246573
1   2   3   4   5   6   7   8   9   ...   13
Bog'liq
Дастурлаш 2 Лаборатория иши 2021 (4)

Laboratoriya ishi №:4 Buferlashtirilgan kiritish va chiqarish


Ishning maqsadi:
Kerakli jixoz va vositalar: kompyuter, proyektor
Nazariy ma’lumot.
Buferlashtirilgan kiritish va chiqarish. C++ tilida ekran va faylga IO dan tashqari kiritish va chiqarish vazifalarini mahalliylash uchun massivlardan foydalanadigan qator funksiyalarni qo'llab-quvvatlaydi. Massivlarga asoslangan kiritish/chiqarish konseptual (array-based I/O) yechimga o'xshasada, C tilining IO funksiyalari bilan analog(bir-birini o'rnini bosuvchi)dir (ayniqsa, sscanf() va sprintf() funksiyalari). Massivlar yordamida kiritish/chiqarish C++ tilida juda moslashuvchan va foydalidir, chunki unda foydalanuvchi tomonidan yaratilgan o'zgaruvchilarni kiritish va chiqarishda ham foydalaniladi. Massivlar bilan kiritish/chiqarishning barcha jihatlarini qamrab olish mumkin emas, ammo, eng muhim va tez-tez ishlatiladigan xususiyatlari amalga oshirish mumkin. Massivlar yordamida IO ni amalga oshirish uchun ham oqimlarni talab qilishini tushunish muhimdir. Oldingi ko'nikmalaringizdan C++ da IO amalarini bilishingiz mumkin. Biroq, kiritish/chiqishda parametrlar sifatida obyektlardan foydalanishning barcha afzalliklari haqida dasturchilarning ko'nikmalari muhimdir. Shuningdek, ma'lumot olish uchun, siz bir necha yangi xususiyatlarni boshqaradigan funksiyalar bilan tanishishingiz kerak. Bu funksiyalar istalgan oqimni ma'lum xotira maydoniga bog'lash uchun mo'ljallangan. Bu amallar tugagandan so'ng. barcha IO xusisiyatlari allaqachon dasturchi biladigan IO vazifalari yordamida amalga oshiriladi degan ko'nikmaga olib keladi. Kiritish/chiqarish obyektlari sifatida massivdan foydalanishni boshlashdan oldin, kutubxonasini dasturingizga kiritilgan bo'lishi kerak. Bu kutubxonadagi istrstream, ostrstream, va strstream sinflardan foydalanish mumkin. Bu sinflar, o'z navbatida, kiritish, chiqish va kirish/chiqish uchun oqimlardan foydalanish asoslangan. Ios sinfi bu sinflar uchun tayanch sinfdir, shuning uchun istream, ostream va iostream sinflarining barcha funksiyalari va manipulyatorlari istrstream, ostrstream va strstream sinflarida ham mavjud. Satr massivini chiqish uchun ostrstream sinf konstruktordan quyidagi asosiy shaklda foydalaniladi: ostrstream chiqish oqimi (char size, openmode mode = ios::out); *bufer, streamsize
Bu yerda, chiqish_oqimi massivli satr bilan bog'laydigan oqim bo'lib, buffer pointer (buferlangan ko'rsatkich) orqali beriladi, size parametri massivning o'lchamini belgilaydi. mode - bu standart rejim parametri, odatda normal chiqish holatiga o'rnatiladi, lekin siz ios sinfda belgilangan har qanday chiqish rejimi indentifikatori o'rnatishingiz mumkin. Chiqish uchun massiv ochilganda, simvolar massivga sig'guncha joylashtiriladi. Toʻlgan massiv bo'lishi mumkin emas. Ixtiyoriy to'lgan massiv kiritish/chiqarishni xatolikka olib kelishi mumkin. Masssivdagi belgilar sonnini aniqlash uchun pcount() funksiya-a'zosi ishlatiladi. int pcount().
Funksiya faqat bir oqim bilan aloqada bo'lib, shu munosabati bilan chaqiriladi va u massivga yozilgan belgilar sonini qaytaradi. Shu jumladan null tugatishni bildiradi. Undan massivga kiritish uchun istrstream sinf konstruktorining quyidagi shaklidan foydalaniladi. istrstream kirish_oqimi (const char* bufer); Bu yerda, bufer belgilar kiritiladigan massivga ko'rsatkich hisoblanadi va kirish_oqimi kirish oqimi bilan ko'rsatiladi. Biror massivdan kirish ma'lumotlarini o'qishda eof() funksiyasidan foydalaniladi va massivning oxiriga yetganida true qaytaradi. Kirish/chiqish uchun massiv ochish uchun strstream sinf konstruktor quyidagicha shakldan foydalaniladi: strstream kch_oqimi(char* bufer, streamsize size, openmoda mode = ios :: in | ios:: out); Bu yerda, kch_oqimi bu kiritish/chiqish oqimi, belgilar oʻlchamida belgilangan uzunligidagi massivga bufer ko'rsatkich orqali kirish/chiqish obyekti sifatida ishlatiladi.
Yuqorida keltirilgan barcha 10 vazifalari, shuningdek, oqim bilan ishlash, ikkilik, shu jumladan tasodifiy kirish uchun muhimligini tushinish lozim.
Massivlar uchun oqim sinflaridan foydalanish C++ standarti tomonidan kam qo'llab-quvvatlanadi.
Laboratoriya ishi No 4
Buferlangan kirish va chiqish
Standart kutubxonadan oqimlar kuchli vositalardir. Funktsiyaning argumenti sifatida oqimni belgilashingiz mumkin va bu uning ko'p qirraliligini ta'minlaydi: u standart fayllar (fstream) va konsol (cin / cout) bilan ham, tegishli kutubxonani topsangiz, rozetkalar va COM portlari bilan ham ishlashi mumkin. .
Biroq, tegishli funksionallik allaqachon amalga oshirilgan tayyor kutubxonani topish har doim ham mumkin emas, ehtimol siz o'z sinflaringiz bilan o'z kutubxonangizni rivojlantirayotgandirsiz. Keyin ip interfeysini o'zimiz amalga oshirish muammosi paydo bo'ladi.
I/U oqimini qo‘llab-quvvatlaydigan har bir sinf std :: istream (kirish), std :: ostream (chiqish) yoki std :: iostream (kirish va chiqish) ni meros qilib oladi. Ular haddan tashqari yuklangan '<<' va '>>' operatorlaridan foydalanish, chiqishni formatlash, raqamlarni satrlarga va aksincha o'zgartirish imkoniyatini beradi.
Biroq, ma'lumotlarni to'g'ridan-to'g'ri o'qish yoki yozish unda emas, balki std :: streambuf ni meros qilib olgan sinfda sodir bo'ladi. O'z-o'zidan, streambuf - bu meros bo'lib qolgan sinfda qayta aniqlanishi kerak bo'lgan va ma'lumotlarni o'qish/yozish uchun o'z mantig'ini amalga oshirish uchun allaqachon mavjud bo'lgan virtual funktsiyalar to'plamiga ega interfeys (bu std :: filebuf va faylda aynan shunday qilingan). std :: fstream va stringstream uchun stringbuf sinflari).

Bundan tashqari, streambuf bufer bilan ishlash mantiqining bir qismini amalga oshiradi. Dasturchi faqat buferning boshi va oxirini o'rnatishi va uning to'lib ketishi, to'lib ketishi, sinxronizatsiyasi va hokazolar uchun hodisa ishlov beruvchilarini amalga oshirishi kerak.


O'z oqimlaringizni ishlab chiqishda eng qiyin qismi std :: streambuf merosxo'rini amalga oshirishdir. Istream, ostream yoki iostreamdan olingan sinflar oddiy holatlarda umuman bo'lmasligi mumkin.
Oddiy holatlar - buferlash yo'q
Oddiy holatda yoki ishlash muhim bo'lmasa, buferlar kerak bo'lmasligi mumkin. Keyin faqat uchta virtual funktsiyani qayta belgilash kifoya:
• int overflow (int c) - buferni to'ldirishda chaqiriladi. Argument buferga mos kelmagan belgidir.
Qaytarilgan qiymat: agar muvaffaqiyatli bo'lsa, yozma belgining kodi int turiga o'tkaziladi, aks holda EOF.
Standart xatti-harakatlar: har doim EOF ni qaytaradi.
• int underflow () - keyingisiga o'tmasdan joriy belgini olish uchun chaqiriladi.
Qaytarilgan qiymat: agar muvaffaqiyatli bo'lsa, o'qilgan belgining kodi int turiga o'tkaziladi, aks holda EOF.
Standart xatti-harakatlar: agar bufer mavjud bo'lsa va o'qilmagan belgilar mavjud bo'lsa, u belgini buferdagi joriy holatiga qaytaradi, aks holda EOF.
• int uflow () - quyi oqim bilan bir xil, lekin muvaffaqiyat bilan bufer ko'rsatgich keyingi belgiga o'tadi.
Qaytish qiymati: quyi oqimdagi kabi.
Standart xatti-harakatlar: qo'ng'iroqlar past oqim. Natija muvaffaqiyatli bo'lsa, u bufer ko'rsatkichini keyingi belgiga o'tkazadi va underflow chaqiruvining natijasini qaytaradi; muvaffaqiyatsiz bo'lsa, u EOF ni qaytaradi. Noma'lum bufer ko'rsatkichini ko'chirishga urinish segmentatsiya xatosiga olib keladi, agar siz buferdan foydalanmasangiz, bu xatti-harakatni bekor qilishni unutmang!
Keyinchalik, funktsiyalar tavsifi cppreference.com dan olingan
1-misol - raqamlarni filtrlash
Balki hozircha matn yetarlidir. Misol tariqasida, faqat raqamlar va bo'shliqlarni o'tkazishga imkon beradigan filtrlash oqimini tahlil qilaylik (raqamlar qandaydir tarzda bir-biridan ajratilishi uchun), ma'lumotlarning o'zi boshqa oqimdan olinadi.
Kod
Dastur natijasi:
Asl: "4 baytda 32 bit mavjud"
Numfilterdan o'qing: '4 32'
Asl nusxasi: "Unix vaqti 1970 yil 1 yanvardan boshlanadi"
Numfilterga yozilgan: '1 1970'

Koddagi asosiy fikrlar allaqachon izohlangan, ammo shuni ta'kidlash kerakki, o'qish uchun ikkala funktsiyani - uflow va underflowni ham amalga oshirish muhim, chunki underflow uflowdan oldin va hatto bir necha marta ketma-ket chaqirilishi mumkin. Agar siz ushbu funksiyalarning boshiga disk raskadrovka chiqishini qo'shsangiz, masalan, oqimdan butun son o'zgaruvchiga o'qiyotganda buni aniq ko'rishingiz mumkin.


Shuningdek, kodda siz char_type turidan foydalanishni sezgan bo'lishingiz mumkin. U streambuf sinfida aniqlanadi va bizning holatlarimizda u char turiga taxallusdir, ya'ni. bir baytli belgi. Bu haqda ko'proq maqolaning oxirida muhokama qilinadi.
Buferlardan foydalanish
Yuqorida aytib o'tganimdek, streambuf allaqachon bufer bilan ishlash mantig'ining bir qismini amalga oshiradi va kirish va chiqish buferlariga 6 ta ko'rsatgich, har biri 3 ta ko'rsatkichga kirishni ta'minlaydi. Biroq, streambuf bufer ajratishni amalga oshirmaydi. Bu vazifa bufer ko'rsatkichlarini ishga tushirish bilan birga dasturchiga qoldiriladi.
Kirish buferi uchun ko'rsatkichlar quyidagicha:
• eback () (oxirgi orqa ko'rsatkich) - buferning birinchi elementiga ko'rsatgich
• gptr () (ko'rsatkichni olish) - keyingi o'qiladigan bufer elementiga ko'rsatgich
• egptr () (end get pointer) - buferning oxirgi elementidan keyingi elementga ko'rsatgich. Gptr unga yetganda, bu bufer tugaganligini va uni to'ldirish kerakligini bildiradi.

mr-edd.co.uk saytidan vizual tasvir


Quyidagi funksiyalar kirish bufer ko'rsatkichlarini boshqarish uchun ham ishlatiladi:
• setg (eback, gptr, egptr) - mos keladigan ko'rsatkichlarning qiymatlarini o'rnatadi
• gbump (ofset) - gptr ko'rsatkichini ofset pozitsiyalari bo'yicha siljitish.

Download 297.3 Kb.

Do'stlaringiz bilan baham:
1   2   3   4   5   6   7   8   9   ...   13




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling