Buferlashtirilgan kiritish va chiqarish

Buferlashtirilgan kiritish va chiqarish. C++ tilida ekran va faylga IO dan tashqari kiritish va chiqarish vazifalarini lokalizatsiyalash sifatida massivlardan foydalanadigan qator funksiyalarni qo‘llab-quvvatlaydi. Massivlarga asoslangan kiritish / chiqarish konseptual (array-based I/O) echimga o‘xshasada, C tilining IO funksiyalari bilan anologdir (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 IOni amalga oshirish uchun ham oqimlarni talab qilishini tushunish muhimdir. Oldingi ko‘nikmalaringizdan C++ da IO amalarini bilishingiz mumkin. Biroq, kiritish/chiqishda paramertlar sifatida obʻyektlardan 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 obʻyektlari 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 *bufer, streamsize size, openmode mode = ios::out);
|
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. Masssivdag belgilarni sonnini aniqlash uchun pcount() funksiya-aʻzosi ishlatiladi.
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‘rsatgich hisoblanadi va kirish_oqimi kirish oqimi bilan ko‘rsatiladi. Biror massivdan kirish maʻlumotlarini o‘qishda eof() funksiyasidan foydalaniladi va massivning oxiriga etganida 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 kirio‘/chiqish oqimi, belgilar o‘lchamida belgilangan uzunligidagi massivga bufer ko‘rsatkich orqali kirish/chiqish obʻyekti sifatida ishlatiladi.
Yuqorida keltirilgan barcha IO vazifalari, shuningdek, oqim bilan ishlash, ikkilik, shu jumladan tasodifiy kirish uchun muhimligini tushinish lozim.
Massivlar uchun oqim sinflaridan foydalanish C++ standarti tomonidan kam ko‘llab quvvatlanadi. Kelajakda C++ versiyalarida qo‘llab-quvvatlanishi bo‘lmasligi ham mumkin. Belgilarni massivla oqimlari uchun mo‘ljallangan bir xil vazifalar C++da sinf-konteyner asosida takomillashtirilgan.
Massivga maʻlumotlarni yozish va chiqish uchun oddiy misol keltiramiz. 1.16-dastur. Massivga chiqarish.
#include "stdafx.h"
#include #include using namespace std; int main(){
char buf[255]; // chiqarish uchun bufer
ostrstream ostr(buf, sizeof buf); // chiqarish uchun massiv ostr << "kirish/chiqish massiv oqimi bilan ishlaydi.\n"; ostr << "oddiy kirish/chiqish kabi: \n " << 100;
ostr <<' ' << 123.23 <<'\n';
// manipulyatordan ham foydalanish mumkin ostr << hex << 100 << ' ';
// identifikatordam ham ostr.setf(ios::scientific); ostr << 123.45 << ' ';
ostr << ends;
// oxirgi natijani chiqarish cout << buf; system("pause");
return 0;
}
|
1.16 – dastur natijasi. Output
|
kirish/chiqish massiv oqimi bilan ishlaydi.
|
oddiy kirish/chiqish kabi:
100 123.23 64 1.234500e+002
|
Dasturda IO operatorlari qayta aniqlangan, hamda kirish/chiqish uchun ajralmas manipulatorlar, aʻzo funksiyalari va massivdvn foydalanishda to‘liq format indentifikatorlari oqimlar uchun foydalanilgan. Bu barcha manipulyatorlar uchun amal qiladi va lokal sinflar uchun IO operatorlari yaratish imkonini beradi.
Yuqoridagi dasturda ends manipulyatori massivga tugatish null belgisini qo‘shish uchun ishlatiladi. Null belgi avtomatik ravishda massivga kiritilgan yoki yo‘qligini amalga oshirish dasturchining o‘ziga bog‘liq. Shuning uchun, bu dasturchi uchun muhim, chunki massiv qatorining oxiriga null belgi yozish yaxshidir.
1.17-dastur. Massivga maʻlumotlarni kiritish.
#include "stdafx.h"
#include #include using namespace std; int main(){
char buf[] = "SalomBuxoro 1980 28.01 B"; istrstream istr(buf);
char str[80]; float f; char c; int i; istr >> str >> i >> f >> c;
cout << str << ' ' << i << ' ' << f << ' ' << c << '\n'; system("pause");
return 0;
}
|
1.17 – dastur natijasi. Output
|
SalomBuxoro 1980 28.01 B
|
Bu dastur bufer ko‘rsatkichida massivda mavjud maʻlumotlarni o‘qiydi va qayta ishlab ekranga chiqaradi.
Agar massiv oqim bilan bog‘langan bo‘lsa, fayl kabi ishlatiladi. Masalan, massiv maʻlumotlarni bufer ko‘rsatkichi bilan o‘qish va dasturda eof() va get() foydalanishni ifodalaydi.
1.18-dastur. Massivlar asosida eof() va get() funksiyalarning IO da foydalanish.
#include "stdafx.h" #include #include using namespace std; int main(){
char buf[] = "SalomBuxoro 1980 28.01 B"; istrstream istr(buf);
char c; while(!istr.eof()) {
istr.get(c);
if (!istr.eof()) cout << c;
}
cout}
|
1.18 – dastur natijasi. Output
|
SalomBuxoro 1980 28.01 B
|
Quyidagi dastur massiv maʻlumotlarni kiritish va chiqarishga oid. 1.19-dastur. Massivlar yordamida kirish/chiqish.
#include "stdafx.h" #include #include using namespace std; int main(){
char iobuf[255];
strstream iostr (iobuf, sizeof iobuf) ; iostr << "tekshrish \n";
iostr << 100 << hex << ' ' << 100 << ends; char str[80]; int i ;
iostr.getline(str, 79); iostr >> dec >> i;
cout << str << ' ' << i << ' '; iostr >> hex >> i;
cout << hex << i << endl; system("pause");
return 0;}
|
Buferlashtirilgan kiritish va chiqarishda C++ da IO ni boshqarish vazifalari uchun aʻzo funksiyalarini, identifikatorlarni va manipulyatorlarni formatlash orqali taʻminlanadi. Indentifikatorlar, funksiyalar va manipulyatorlar bir xil vazifani bajaradi - ular axborotni kiritish/chiqarish uchun maxsus formatni o‘rnatadi. C++ da ekrandan/ga kiritish/chiqarish mos ravishda cin va cout operatorlari yordamida amalga oshiriladi, yaʻni formatlash manipulyatorlari ushbu IO operatorlari bilan birgalikda ishlatiladi. Indentifikator vazifalari va formatlash manipulyatorlar o‘rtasidagi farq ularga qo‘llaniladigan usuldir. Endi formatlash obektlaridan foydalanish yo‘llarini ko‘rib chiqamiz.
Asosiy formatlash aʻzo funksiyalari:
cout.fill('symbol'); to‘ldiruvchi belgini o‘rnatadi. Bunda symbol to‘ldiruvchi belgi va tirnoq ichida beriladi.
cout.width(width_field); maydon uzunligini berish. width_field – pozitsiyalar soni, har bir pozitsiyada bitta simvol sig‘adi.
cout.precision(number); haqiqiy sonlarda nuqtadan keyingi belgilar soni berish. number - haqiqiy sonlarda nuqtadan keyingi belgilar soni.
Funksiyalarga nuqta amali orqali kirishiladi va qavslar ichida kerakli argument yoziladi. Fill() funksiyasiga argumentni bitta qo‘shtirnoq bilan belgi sifatida yoki son(belgi kodi) sifatida yozish mumkin. kirish/chiqish oqimlarni formatlash uchun bitta funksiya yetarli emas. C++da indentifikatorlar bilan formatlash usullarini ko‘ramiz.
Indentifikatorlar orqali formatlash kirish/chiqish parametrlaridan birini yoqish yoki o‘chirish imkonini beradi. IO nindentifikatorni o‘rnatish uchun setf() funksiyasini ishlatamiz va agar chiqish indentifikatorni o‘chirmoqchi bo‘lsangiz, unsetf() funksiyasidan foydalaniladi. Quyidagi indentifikatorni o‘rnatish va o‘chirishga doir instruksiya ko‘rsatilgan.
Chiqish indentifikatorni o‘rnatish
cout.setf( ios::name_flag );
|
name_flag - indentifikator nomi. Chiqarish operatorlariga nuqta orqali ruxsat beriladi. setf() funksiyasi bitta argument qabul qiladi va indentifikator nomidir. Indentifikatorlar ios sinfiga tegishli bo‘lganligi uchun oldin shu sinf nomi yoziladi va kengaytirish amali orqali kerakli indentifikator tanlanadi.
Chiqish indentifikatorni o‘chirish
cout.unsetf( ios::name_flag);
|
name_flag - indentifikator nomi.
Agar kirish/chiqishda bir nechta identifikatorlarni ishlatish kerak bo‘lsa, Yoki [|] mantiqiy amalidan foydalanish mumkin.
Bir nechta identifikatorlarni o‘rnatish
cout.setf( ios::name_flag1 | ios:: name_flag2 | ios:: name_flag_n );
|
Bir nechta identifikatorlarni o‘chirish
cout.unsetf( ios::name_flag1 | ios:: name_flag2 | ios:: name_flag_n );
|
1.1-jadval asosiy formatlash identifikatorlarini keltirilgan va ulardan foydalanishga doir misollar ko‘rsatilgan.
1.1-jadval. C++ da formatlash identifikatorlari.
Identifi-
kator
|
Vazifasi
|
misol
|
Misol
natija-si
|
boolalpha
|
Mant ko‘rinishida mantiqiy kattalikni kiritish (true, false)
|
cout.setf(ios::boolalpha); bool log_false = 0, log_true = 1;
cout << log_false << endl
<< log_true << endl;
|
false true
|
oct
|
Sakkizlik sanoq sistemasida kattaliklarni kiritish (avval dec
identifikatorni o‘chiramiz
|
cout.unsetf(ios::dec); cout.setf(ios::oct); int value;
cin >> value;
|
kirish: 9910
chiqish:
1438
|
|
va oct identifikator
o‘rnatamiz )
|
cout << value << endl;
|
|
dec
|
O‘nlik sanoq sistemasida kattaliklarni kiritish/chiqarish (identifikator joriy
o‘rnatilgan)
|
cout.setf(ios::dec); int value = 148;
cout << value << endl;
|
148
|
hex
|
O‘n oltilik sanoq sistemasida kattaliklarni kiritish (avval dec identifikatorni o‘chiramiz va oct identifikator
o‘rnatamiz )
|
cout.unsetf(ios::dec); cout.setf(ios::hex); int value;
cin >> value;
cout << value << endl;
|
kirish: 9910
chiqish: 6316
|
showbase
|
Sanoq sistemaga asoslangan indikatorni chiqarish
|
cout.unsetf(ios::dec); cout.setf(ios::oct | ios::showbase);
int value;
cin >> value;
cout << value << endl;
|
kirish: 9910
chiqish: 01438
|
uppercase
|
16 lik SSda katta harflarni chiqarish (joriy holatda kichik harflar o‘rnatilgan)
|
cout.unsetf(ios::dec); cout.setf(ios::hex | ios::uppercase);
int value;
cin >> value;
cout << value << endl;
|
kirish: 25510
chiqish: FF16
|
showpos
|
Musbat sonlar uchun + ishorasini chiqarish
|
cout.setf(ios::showpos); int value = 15;
cout << value << endl;
|
+15
|
scientific
|
Eksponensial sonlarni
chiqarish
|
cout.setf(ios::scientific);
double value = 1024.165;
|
1.024165
e+003
|
|
|
cout << value << endl;
|
|
fixed
|
Fiksirlangan holda haqiqiy sonlarni chiqarish
(joriy holatda)
|
double value = 1024.165; cout << value << endl;
|
1024.165
|
right
|
O‘ng tomondan tekslish
|
cout.width(40);
cout << «cppstudio.com»
<< endl;
|
cppstu dio.com
|
left
|
Chap tomondan tekislash
|
cout.setf(ios::left); cout.width(40);
cout << «cppstudio.com»
<< endl;
|
cppstudio
.com
|
Shuningdek, monipulyatorlar bilan formatlashning usullari ham bor. manipulyator – maxsus tip bo‘lib, oqimlarga o‘tgan maʻlumotlarni formatlash uchun kiritish/chiqish oqimlarni nazorat qiladi. Lekin, ko‘pchilik manipulatorlarining funksiyalari identifikatorlar bilan bir xil formatlash amallarini bajaradi. Baʻzida, identifikatorli yoki formatlash funksiyalaridan foydalanish osonroq bo‘lsada, baʻzan formatlashda manipulyatorlaridan foydalanish qulayroq. Shuning uchun C++da kirish / chiqishni formatlashning bir necha vositalari bilan to‘ldirilgan. 1.2-jadvalda formatlashning monipulyatorlari va misollari keltirilgan.
1.2-jadval. Formatlashning monipulyatorlari.
Manipulyator
|
vazifasi
|
misob
|
natijasi
|
endl
|
Chiqarishda yangi qatorga o‘tish
|
cout <<
«Salom:» << endl <<
«mbbGroup»;
|
website: cppstudio.com
|
boolalpha
|
Mantiqiy kattalikni matn
ko‘rinishida chiqarish (true, false)
|
bool log_true = 1;
cout <<
|
true
|
|
|
boolalpha << log_true <<
endl;
|
|
noboolalpha
|
Mantiqiy kattalikni son ko‘rinishida chiqarish (true, false)
|
bool log_true = true;
cout << noboolalpha << log_true <<
endl;
|
1
|
oct
|
8 SSda sonlarni chiqarish
|
int value = 64; cout << oct <<
value << endl;
|
1008
|
dec
|
10 SSda sonlarni chiqarish
|
int value = 64;
cout << dec << value << endl;
|
6410
|
hex
|
16 SSda sonlarni chiqarish
|
int value = 64; cout << hex <<
value << endl;
|
408
|
showbase
|
SS uchun asosiy indikatorni chiqarish
|
int value = 64; cout << showbase << hex << value <<
endl;
|
0x40
|
noshowbase
|
SS uchun asosiy indikatorni chiqarmaslik
(joriy holat).
|
int value = 64; cout << noshowbase << hex << value <<
endl;
|
40
|
uppercase
|
16 SS da katta harflarni
|
int value = 255;
|
FF16
|
|
chiqarish (joriy holatda kichik harflar)
|
cout << uppercase << hex << value <<
endl;
|
|
nouppercase
|
16 SS da kichik harflarni chiqarish (joriy holat)
|
int value = 255; cout << nouppercase << hex << value <<
endl;
|
ff16
|
showpos
|
Sonlarni + belgisi bilan chiqarish
|
int value = 255; cout << showpos<<
value << endl;
|
+255
|
noshowpos
|
Sonlarni + belgisiz chiqarish (joriy holat)
|
int value = 255; cout
|
255
|
scientific
|
Sonlarni eksponensial ko‘rinishda chiqarish
|
double value = 1024.165;
cout << scientific <<
value << endl;
|
1.024165e+003
|
fixed
|
Fiksirlash holda sonlarni chiqarish (joriy holat).
|
double value = 1024.165;
cout << fixed
<< value << endl;
|
1024.165
|
setw(int number)
|
Maydon uzunligini o‘rnatish, number — simvollarning
pozitsiyalari soni,
|
cout << setw(40) <<
“mbbGroup” <<
|
mbbGroup
|
|
parameterli monupulyator
|
endl;
|
|
right
|
O‘ngdan tekslash
|
cout << setw(40) << right << « mbbGroup » <<
endl;
|
mbbGroup
|
left
|
Chapdan tekislash
|
cout << setw(40) << left
<< « mbbGroup
» << endl;
|
mbbGroup
|
setprecision(int count)
|
Verguldan keyi kalit belgi berish, count — verguldan keyingi belgilar soni
|
cout << fixed
<<
setprecision(3)
<< (13.5 / 2) <<
endl;
|
6.750
|
setfill(int symbol)
|
Qo‘shimcha belgilarni o‘rnatish
|
cout << setfill(‘0′) << setw(4) << 15
<< ends <<
endl;
|
0015
|
C++ da buferlashtirilgan formatlangan kirish/chiqish dasturlashdagi eng oddiy mavzulardan biri hisoblanadi. Maʻlum formatlash vositalaridan qanday foydalanish yuqoridagi jadvallarda ko‘rsatilgan, shuning uchun bu mavzuda hech qanday qiyinchilik bo‘lmasligi kerak.
Nazorat savollari
Polimorf sinf qanday xususiyatga ega bo‘lishi lozim?
Dastur bajarilishi davomida obʻyekt turini olish uchun qanday operatordan foydalaniladi?
type_info sinfda public modifikatori bilan qaysi statik operatorlar aniqlangan?
Type_info sinf aʻzolaridagi qanday operatordan foydalanish taqiqlangan?
Typeid operatorini havolali parametriga qo‘llash mumkinmi?
C++ tilida necha tipni almatirish operatorlari mavjud va ularni nomlari, ishlatish uslublarini ayting.
Dynamic_cast operatori dastur bajarilishi davomida qaysi turdagi quyish amalini bajaradi?
Dynamic_cast va const_cast tip almashtirish operatorlarining vazifalari, kamchiliklari va yutuqlari eslang.
O‘zgarmas eʻlon qilingan identifikatorning tipini almashtirish mumkinmi. Mumkin bo‘lsa qanday amalga oshiriladi. Mumikn bo‘lmasa, nima sababdan izohlayu bering.
Polimorf bo‘lmagan va bo‘lgan sinf obʻyektining tipini almashtirish uchun qaysi operatorlardan foydalaniladi, har birini izog‘layu bering.
To‘rtta cast operatorlari dynamic_cast, const_cast, static_cast, reinterpret_cast bilan anʻanaviy tipni almashtirish amali (kasting) qanday farq mavjud.
Yangi nomlar fazosi yaratish uchun kerak, misollar bilan eslab tushuntirib bering.
Jamoaviy dasturlash vaqtida dasturdaga nomlarning ziddiyatlarni oldini olish uchun nima vazifani amalga oshrish kerak va ziddiyatlarni bekor qilishning eng oddiy va professonal usulini tushuntiring.
Nomlar fazosini 2 ga ajratish mumkinmi, mumkin bo‘lsa, qanday va nima uchun nomlar fazosini 2 ga ajratish kerak bo‘ladi.
Using kalit so‘zni ishlatmasdan turib, nomlar fazosiga murojaat qilish mumkinmi? Mumkin bo‘lsa, misol bilan asoslab bering.
C++ tilida ekran va faylga IO dan tashqari kiritish va chiqarish vazifalarini lokalizatsiyalash sifatida qanday vositadan foydalanadigan qator funksiyalarni qo‘llab-quvvatlanadi.
Kiritish/chiqarish obʻyektlari sifatida massivdan foydalanish uchun qanday header fayldan foydalanish lozim.
Massivga maʻlumotlarni yozish va chiqish uchun qanday tipdan foydalaniladi.
Massivlar asosida eof() va get() funksiyalarning IO da foydalanish nima uchun zarur.
Kirish/Chiqish indentifikatorni o‘rnatish va o‘chirish usullari aytib bering va misollar orqali asoslang.
Formatlash identifikatorlari nima uchun kerak va u qanday ishlatiladi.
Sanoq sistemaga asoslangan indikatorni chiqarish uchun qaysi formatlash identifikatoridan foydalanamiz.
Chap tomondan tekislab formatlashda qaysi formatlash identifikatoridan foydalanamiz.
Monipulyatorlar bilan formatlashning usullari nima uchun kerak va u qanday ishlatiladi.
Sanoq sistemaga asoslangan indikatorni chiqarish uchun qaysi monipulyatorlar bilan formatlashning usuldan foydalanamiz.
|