Dasturlash sayohatingizda siz haqiqiy ma'lumotlar bilan ishlashni boshlashni xohlaydigan vaqt keladi. Bunday ma'lumotlar odatda diskdagi fayllarda saqlanadi. Fayllardan o'qish operatsion tizimingiz bilan ishlashni o'z ichiga olganligi sababli, bu juda murakkab vazifadir. Ushbu maqolada biz C++ oqimlarini, fayllar bilan ishlashni va fayldan C++ dasturiga maʼlumotlarni oʻqishning uch xil usulini koʻrib chiqamiz.
Agar siz Python kabi yuqori darajadagi dasturlash tilidan kelgan bo'lsangiz, faylni dasturda o'qish juda oddiy vazifaga o'xshaydi. Siz faylni ochasiz, mazmunini o'qiysiz va uni yopasiz. Fayl bilan ishlash kodingizning bir yoki ikki qatorini egallashi mumkin. C++ da faylni oʻqish jarayoni biroz murakkabroq – oqim obyektiga yoki undan oʻqishning qoʻshimcha bosqichi mavjud. Bizning C++ dasturlarimiz fayllar bilan qanday o'zaro ta'sir qilishini tushunish uchun keling, endi C++ tilidagi oqimlar tushunchasini ko'rib chiqaylik.
C++ oqimlari nima?
C++ oqimlari ketma-ketlikka o'xshash kirish va chiqishni qayta ishlash uchun interfeyslardir. Agar siz ilgari C++ da “Salom Dunyo” dasturini yozgan bo‘lsangiz, demak, siz oqimlar bilan ishlagansiz. Keling, bu qanday ko'rinishini qisqacha ko'rib chiqaylik:
std::cout << "Salom dunyo!\n";
Ushbu misolda biz string ob'ektimizni belgilar chiqish oqimiga (qisqacha "cout") uzatamiz. cout iostream kutubxonasining bir qismi va chiqish oqimlarining umumiy sinfiga («ostream») misoldir. ostreamning singlisi sinfi "istream", kirish oqimlarini boshqarish uchun sinfdir.
Fayllar bilan ishlashda biz oqimlarning yana bir quyi sinfidan foydalanamiz: fstream sinfi (fayl oqimi uchun) kirish uchun ifstreams va faylga chiqarish uchun oqim oqimlaridan iborat. Ushbu misol uchun biz ifstreams bilan ishlaymiz, chunki ular bizga fayldan o'qish imkonini beradi.
C++ da fayllar bilan ishlash
Matn faylidagi belgilar ketma-ketligini o'qish uchun biz quyidagi amallarni bajarishimiz kerak:
Oqim obyektini yarating.
Uni diskdagi faylga ulang.
Fayl mazmunini bizning oqim ob'ektimizga o'qing.
Faylni yoping.
Quyida biz batafsil koʻrib chiqadigan qadamlar “fayllarni qayta ishlash” amali ostida roʻyxatdan oʻting. Har bir bosqichda bizning oqim ob'ektimiz turli holatlarni egallashi mumkin, biz ularni quyidagi a'zo funktsiyalaridan foydalanishni tekshirishimiz mumkin:
bad() oqimidan oʻqish yoki oqimga yozishda xatolik yuz bergan boʻlsa, True qiymatini qaytaradi. Agar oqim "yomon" bo'lsa, oqim bilan bog'liq boshqa operatsiyalarni amalga oshirish mumkin emas.
Agar xatolik yuzaga kelsa fail() True qiymatini qaytaradi, lekin biz oqimda ishlashimiz mumkin.
eof() faylning oxiriga (EOF) erishilsa, True qiymatini qaytaradi, aks holda False qaytariladi.
good() rostni qaytaradi, agar qolgan uchta holatning har biri noto'g'ri bo'lsa, ya'ni oqim na yomon, na muvaffaqiyatsiz, na faylning oxiriga yetmagan bo'lsa.
Yana bir muhim usul is_open() tomonidan taqdim etiladi. Agar oqim ob'ekti ochiq bo'lsa, u True deb baholanadi. Keling, nihoyat barcha komponentlarni birlashtiramiz va C++ faylida o'qiymiz.
C++ da faylni o'qing
Aytaylik, bizda .txt faylida saqlangan xaridlar ro‘yxati bor:
tuxum jambon tuxum va spam spam va tuxum
Bizning maqsadimiz ro'yxat tarkibini konsolga chop etishdir. Dasturimizni yozishni boshlashdan oldin keling, tegishli sarlavha fayllarini kiritamiz:
#include #include #include
Endi funksiyamizni yozishga tayyormiz. Keling, avval fstream o'zgaruvchimizni e'lon qilamiz va faylni ochish orqali uni oqim ob'ektiga ulaymiz:
int main () { std::ifstream mening faylim; myfile.open("shopping_list.txt");
To'g'ridan-to'g'ri aytganda, biz oqim ob'ektini ishga tushirishda faylni to'g'ridan-to'g'ri ochish uchun sinf konstruktoridan foydalanib, bu amalni bitta satrda bajarishimiz mumkin edi:
int main () { std::ifstream myfile ("shopping_list.txt"); // bu yuqoridagi usulga teng
Fayl mazmunini oqimimizga o‘qishdan oldin, faqat tarkibni o‘z ichiga oladigan satr o‘zgaruvchisini e’lon qilish qoladi:
std::string mystring;
>> Operator yordamida faylni C++ da o'qing
Yangi boshlanuvchilar uchun fayldan ro‘yxatimizni o‘qish uchun oqim kiritish operatoridan >> foydalanamiz.
if ( myfile.is_open() ) { // har doim fayl ochiqligini tekshiring myfile >> mystring; // fayl tarkibini oqimga o'tkazing std::cout << mystring; // quvur oqimining mazmunini standart chiqish }
Esda tutingki, ifstream destruktori faylimizni avtomatik ravishda yopadi, bu bu sinfdan foydalanishning afzalliklaridan biridir. Agar xohlasak, dasturning oxiriga infile.close() buyrug'ini qo'shgan bo'lardik. Bu yaxshi amaliyot sifatida ko'riladi, lekin u hech qanday qiymat qo'shmaydi.
Ushbu funktsiyani ishga tushirganimizda, biz ekranda chiqadigan natijani olamiz:
tuxum
Bu biz kutgan narsa emas. Funktsiyamiz xaridlar ro'yxatining faqat birinchi qismini chop etdi. Buning sababi shundaki, >> operatori satrni faqat bo'sh joy belgisiga (masalan, bo'sh joy yoki qator uzilishi) duch kelmaguncha o'qiydi. Butun faylni o'qish uchun chiziqni while tsikliga joylashtirishimiz mumkin:
if ( myfile.is_open() ) { while ( myfile.good() ) { myfile >> mystring; std::cout << mystring; } }
Faylning oxiriga yetganimizdan so'ng, myfile.good() False qiymatini baholaydi, bu esa while tsiklining tugashiga olib keladi. Shartni quyidagicha qisqartirishimiz mumkin:
while (mening faylim) {
Bu bizning faylimiz yaxshi yoki yo'qligini so'rashga teng. Bizning kodimiz hozir qanday ishlaydi?
tuxumshameggspamspamandeggseggs
Bu erda ikkita narsa sodir bo'ldi: bizning barcha xaridlarimiz bir-biriga bog'langan, oxirgi narsa ikki marta chop etilgan. Ikkinchisi C++ ning buferlangan ma'lumotlarni qanday ishlashi bilan bog'liq bo'lsa-da va bu o'quv qo'llanmasi doirasidan tashqarida bo'lsa-da, birinchisi kutilgan edi. Axir, >> bo'shliqqa e'tibor bermaydi, ya'ni barcha bo'sh joy va yangi qator belgilar yo'qoladi. Ushbu ma'lumotni chiqishga qanday kiritishimiz mumkin? Bu savolga javob get() funksiyasida yotadi.
get() yordamida C++ da faylni oʻqing
Biz >> ni bir vaqtning o'zida bitta belgida o'qiladigan fstream sinfimizning a'zo funksiyasi get() bilan almashtiramiz. get() ning ajoyib tomoni shundaki, u oq bo'shliqni e'tiborsiz qoldirmaydi va buning o'rniga uni oddiy belgilar qatori sifatida ko'radi. Fayl mazmunini toʻliq oʻqish uchun biz while-loopimizga amal qilamiz:
if ( myfile.is_open() ) { char mychar; while ( myfile ) { mychar = myfile.get(); std::cout << mychar; } }
Bizning kichik skriptimizning chiqishi hozir qanday ko'rinishga ega?
tuxum jambon tuxum va spam spam va tuxum
Muvaffaqiyat! Bizning butun xaridlar ro'yxati konsolda chop etildi. Ushbu funktsiya haqiqatan ham har bir belgini birma-bir oqimlashini ko'rsatish uchun keling, har bir chiqishdan keyin oqim ko'rsatgichining o'rnini ko'rsatadigan kichik funksionallikni qo'shamiz.
std::cout << ": " << myfile.tellg() << ", " ;
tellg() funksiyasining nomi “tell get” ning qisqartmasi. U kirish oqimi bo'ylab harakatlanayotganda ko'rsatgichning joriy holatini qaytaradi. Butun fayl o'tkazilgandan so'ng tellg() -1 qiymatini qaytaradi.
O'zgartirilgan kodni ishga tushirgandan so'ng chiqishning faqat birinchi ikkita qatorini ko'rib chiqaylik:
e: 2, g: 3, g: 4, s: 5, : 6, h: 7, a: 8, m: 9,
Har bir get() amali uchun standart chiqish kirish harfi va koʻrsatgich oʻrnini koʻrsatadi. Ko'rishimiz mumkinki, har bir belgi alohida-alohida ishlangan bo'lib, kod har bir belgidan keyin ko'rsatgichning o'rnini, xoh u harf yoki bo'sh joy bo'lsin, baholaydi.
Getline() yordamida C++ da faylni oʻqing.
Bizning foydalanish holatlarimiz uchun har bir belgini alohida qayta ishlashning ma'nosi yo'q - oxir-oqibat, biz xaridlar ro'yxatidan ekranga har bir qatorni birma-bir bosib chiqarishni xohlaymiz. Bu getline(), boshqa a'zo funktsiyasini talab qiladi, u matnda satr uzilishiga duch kelmaguncha o'qiydi. Kodimizni qanday o'zgartirishimiz mumkin:
std::string myline; if ( myfile.is_open() ) { while ( myfile ) { std::getline (mening faylim, myline); std::cout << myline << ": " << myfile.tellg() << '\n'; } }
Va mana chiqish:
tuxum: 5 jambon: 9 tuxum va spam: 23 spam va tuxum: 37
Endi ko'rsatgichning joylashuvi bizning fayl oqimimiz tomonidan o'qilgan har bir satrdan keyin baholanadi.
Xulosa qilish uchun, faylni C++ da satr bo‘yicha o‘qish uchun skriptimizning yakuniy versiyasi:
#include #include #include int main (){ std::ifstream myfile; myfile.open("shopping_list.txt"); std::string myline; if ( myfile.is_open() ) { while ( myfile ) { // myfile.good() ga ekvivalent std::getline (mening faylim, myline); std::cout << myline << '\n'; } } else { std::cout << "Faylni ochib boʻlmadi\n"; } qaytish 0; }
Agar muammoli faylga duch kelsangiz, ushbu skript oxirida qilganimizdek, boshqa shartni qo'shsangiz yaxshi bo'ladi. Oddiy so'zsiz tugatish o'rniga, skript sizga faylni ocha olmaganligini aytadi.
C uslubidagi o'qish fayli yordamida C++ da faylni o'qing
C++ tilining ko‘p jihatlarida bo‘lgani kabi, bizda ham o‘qish va fayllarga yozish uchun boshqa sinf mavjud bo‘lib, u o‘zidan oldingi C tilidan qolgan. C uslubidagi oqimlar cstdio kutubxonasidagi FILE obyektlarida kodlangan. stdin va stdout mos ravishda kirish va chiqish oqimlarini boshqarish uchun FILE* tipidagi ifodalardir.
C-uslubidagi fayllarni o'qish bilan fstream sinfidan eng muhim farq shundaki, FILE* obyektlari siz uchun fayllarni yopmaydi: Agar faylingizni yopishni unutib qo'ysangiz, u ochiq qoladi. Shuning uchun fstream sinfining tarafdorlari undan foydalanish xavfsizroq ekanligini ta'kidlaydilar.
C++ dasturchisi bo'lish uchun o'rganing
Fayldan ma'lumotlarni o'z dasturingizga o'qishni o'rganish har qanday C++ dasturchisi uchun muhim qadamdir. Ammo bu tenglamaning faqat bir qismi.
Bizning kursimiz sizni C++ dasturchisiga aylantirish uchun yaratilgan. Beshta real loyiha ustida ishlayotganda asosiy dasturlash tushunchalarini bilib olasiz.
//O'qish va yozish funksiyasidan foydalangan holda ob'ektni yozish va o'qish uchun C++ dasturi.
#include
#include
using namespace std;
//sinf talabasi talaba ma'lumotlarini o'qish va yozish uchun
sinf o'quvchisi
{
private:
belgi nomi[30];
int yoshi;
public:
void getData(void)
{ cout<<"Ismni kiriting:"; cin.getline(ism,30);
cout<<"Yoshni kiriting:"; cin>>yosh;
}
void showData(void)
{
cout<<"Ism:"<
}
};
int main()
{
talaba s;
ofstream file;
//faylni yozish rejimida ochish
file.open("aaa.txt",ios::out);
if(!fayl)
{
cout<<"Fayl yaratishda xatolik.."<
return 0;
}
cout<<"\nFayl muvaffaqiyatli yaratildi."<
// faylga yozing
s.getData();
// foydalanuvchidan o'qish
file.write((char*)&s,sizeof(lar)); // faylga yozing
file.close(); //faylni yoping
cout<<"\nFayl saqlandi va muvaffaqiyatli yopildi."<
// faylni kiritish rejimida qayta oching va ma'lumotlarni o'qing
//1 faylni oching
ifstream fayli 1;
//faylni yana o'qish rejimida oching
file1.open("aaa.txt",ios::in);
if(!fayl1){
cout<<"Faylni ochishda xatolik..";
return 0;
}
//fayldan ma'lumotlarni o'qish
file1.read((char*)&s,sizeof(lar));
// monitorda ma'lumotlarni ko'rsatish
s.showData();
//faylni yoping
C++ da fayldan/faylga sinf ob'ektlarini o'qish/yozish
"Input.txt" fayli berilgan bo'lib, unda har bir satrda sinfning misol o'zgaruvchilari bilan bir xil qiymatlar mavjud.
Sinf ob'ektidagi qiymatlarni o'qing va kerakli operatsiyalarni bajaring.
Ma'lumotlarni uzatish odatda '>>' va <<' operatorlari yordamida amalga oshiriladi. Agar sizda 4 ta maʼlumot aʼzosi boʻlgan sinfingiz boʻlsa va uning obʼyektidagi barcha 4 ta maʼlumot aʼzosini toʻgʻridan-toʻgʻri faylga yoki aksincha yozmoqchi boʻlsangiz, buni quyidagi sintaksis yordamida amalga oshirishimiz mumkin: Faylga obyekt maʼlumotlar aʼzolarini yozish uchun: // Bu yerda file_obj - ofstream faylining ob'ekti file_obj.write((char *) & class_obj, sizeof(class_obj)); Fayl ma'lumotlar a'zolarini ob'ektga o'qish uchun: // Bu erda file_obj - ifstream faylining ob'ekti file_obj.read((char *) & class_obj, sizeof(class_obj));
Do'stlaringiz bilan baham: |