Alkalmazott modul: Programozás 2. előadás. Procedurális programozás: adatfolyamok, adatsorok kezelése. Adatfolyamok kezelése. Adatfolyamok kezelése

Hasonló dokumentumok
Alkalmazott modul: Programozás 2. előadás. Procedurális programozás: adatfolyamok, adatsorok kezelése

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök. Adatfolyamok Hibalehetőségek

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök

Bevezetés a programozásba I 7. gyakorlat. C++: szövegkezelés, szekvenciális fájlkezelés. Szövegkezelés Karakterkezelés

Bevezetés a programozásba I 4. gyakorlat. PLanG: Szekvenciális fájlkezelés. Szekvenciális fájlkezelés Fájlok használata

Bevezetés a programozásba I.

Bevezetés a programozásba I 4. gyakorlat. PLanG: Szekvenciális fájlkezelés

Pénzügyi algoritmusok

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Bánsághi Anna 2014 Bánsághi Anna 1 of 35

Bevezetés Kiíratás Beolvasás Formázás Fájlkezelés Gyakorló feladatok C++ I/O. Bevezetés. Izsó Tamás február 20. Izsó Tamás C++ I/O / 1

Alkalmazott modul: Programozás. Programozási tételek, rendezések. Programozási tételek Algoritmusok és programozási tételek

A C++ nyelvben a függvény nevek túlterhelésével biztonságosabbá tehetnénk az adatok kiírását és beolvasását.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

HORVÁTH ZSÓFIA 1. Beadandó feladat (HOZSAAI.ELTE) ápr 7. 8-as csoport

Bevezetés a programozásba I.

Bevezetés a programozásba. 8. Előadás: Függvények 2.

1. Alapok. Programozás II

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

Bevezetés a programozásba I 3. gyakorlat. PLanG: Programozási tételek. Programozási tételek Algoritmusok

Maximum kiválasztás tömbben

Bevezetés a programozásba I.

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós május 6. Széchenyi István Egyetem, Gy r

Alkalmazott modul: Programozás. Programozási tételek, rendezések Giachetta Roberto

AWK programozás, minták, vezérlési szerkezetek

Programozás II. 2. Dr. Iványi Péter

Programozás Minta programterv a 1. házi feladathoz 1.

Mérnöki programozás 7. Szerkesztette: dr. Vass Péter Tamás

Bevezetés a programozásba I.

AWK programozás, minták, vezérlési szerkezetek

II. Mérés SZÉCHENYI ISTVÁN EGYETEM GYŐR TÁVKÖZLÉSI TANSZÉK

C++ programozási nyelv Struktúrák a C++ nyelvben Gyakorlat

Programozás C++ -ban 2007/1

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Bevezetés a programozásba. 11. Előadás: Esettanulmány

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

INFORMATIKA tétel 2019

Programozási nyelvek Java

Operációs rendszerek. 9. gyakorlat. Reguláris kifejezések - alapok, BASH UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

ELTE SAP Excellence Center Oktatóanyag 1

INFORMATIKA javítókulcs 2016

Programozási nyelvek Java

Programozás I gyakorlat

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 6.ELŐADÁS. Fájlkezelés PHP-ben

Szövegek C++ -ban, a string osztály

8. Gyakorlat. Rövid elméleti összefoglaló: Fájlkezelés

AWK programozás Bevezetés

2018, Funkcionális programozás

INFORMATIKA tétel 2017

7. gyakorlat Sorozatok, Fájlkezelés

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Felvételi tematika INFORMATIKA

Elemi alkalmazások fejlesztése I. Olvassunk be egy fájlból egész számokat egy tömbbe. Keressük meg a tömb valamely

S z á m í t ó g é p e s a l a p i s m e r e t e k

Készítette: Nagy Tibor István

Bevezetés a programozásba. 9. Előadás: Rekordok

Fejlett programozási nyelvek C++ Sablonok és adatfolyamok

7. fejezet: Mutatók és tömbök

Operációs rendszerek gyak.

Bevezetés a C++ programozásba

Programozás C és C++ -ban

Occam 1. Készítette: Szabó Éva

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

Programozás C nyelven (3. ELŐADÁS) Sapientia EMTE

1. Írjunk programot mely beolvas két egész számot és kinyomtatja az összegüket.

BASH script programozás II. Vezérlési szerkezetek

Mintavételes szabályozás mikrovezérlő segítségével

Fejlett programozási nyelvek C++ Iterátorok

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

Gregorics Tibor Egyszerű programok C++ nyelvi elemei 1

Programozás 6. Dr. Iványi Péter

Változók. Mennyiség, érték (v. objektum) szimbolikus jelölése, jelentése Tulajdonságai (attribútumai):

7. gyakorlat. Fájlkezelés IO haladó Függvények haladó

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Gregorics Tibor Egyszerű programok C++ nyelvi elemei 1

3. ZH-ban a minimum pontszám 15

5. Gyakorlat. struct diak {

Java II. I A Java programozási nyelv alapelemei

Bevezetés a programozásba I.

Feladat. Bemenő adatok. Bemenő adatfájlok elvárt formája. Berezvai Dániel 1. beadandó/4. feladat április 13. Például (bemenet/pelda.

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

1. numere.txt n (1 n 10000) n növekvő kilenc a) Pascal/C++ Például: NUMERE.TXT

Programozás C nyelven (13. ELŐADÁS) Sapientia EMTE

C programozás. { Márton Gyöngyvér, 2009 } { Sapientia, Erdélyi Magyar Tudományegyetem }

Programozás alapjai 9.Gy: Struktúra 2.

Informatika terméktervezőknek

Programozás(A szakirány) II. beadandó feladat Farkas András HP6S15 1. csoport Veszprémi Anna / Hudoba Péter

A C programozási nyelv I. Bevezetés

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

1. Jelölje meg az összes igaz állítást a következők közül!

Programozás I gyakorlat. 10. Stringek, mutatók

A C programozási nyelv I. Bevezetés

Operációs rendszerek. 9. gyakorlat. BASH recap, reguláris kifejezések UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Programozási nyelvek Python

Bevezetés a programozásba. 5. Előadás: Tömbök

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Alkalmazott modul: Programozás 2. előadás Procedurális programozás: adatfolyamok, adatsorok kezelése Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto Adatfolyamok C++-ban Adatfolyamnak nevezzünk az adatok összefüggő, nem strukturált, de az elemek sorrendjét megtartó halmazt, amely írható, illetve olvasható pl. konzol képernyő, fájl, hálózati csatorna A C++ az adatfolyamokat hasonló módon kezeli, jórészt ugyanazon műveletek használhatóak minden adatfolyamra hasonló viselkedéssel látja el, pl. ugyanolyan állapotlekérdezést, helyreállítást biztosít olvasó és író műveletekkel látja el: << (olvasás), >> (írás), getline(<adatfolyam>,<szöveg>) (sor olvasás) ELTE IK, Alkalmazott modul: Programozás 2:2 Adatfolyamok olvasása Az adatfolyamokból egyenként olvashatunk adatokat a >> operátorral (szöveg esetén szóközig olvas), vagy soronként Soronként olvasáshoz használható a teljes sor beolvasása egy szövegbe: getline(<adatfolyam>, <szöveg változó>) a sor egy részének beolvasása adott (határoló) karakterig: getline(<adatfolyam>, <szöveges változó>, <határoló karakter>) a határoló karaktert az adatfolyam eldobja, és a következő olvasó művelet utána kezd ha nem találja a határoló karaktert, a teljes sort beolvassa Adatfolyam manipulátorok Az adatfolyamok működését számos módon befolyásolhatjuk, pl.: sortörés (endl), vízszintes tagolás (left, right, internal) kiírás számrendszere (dec, hex, oct), valós számok formátuma (fixed, scientific) whitespace karakterek átugrása (skipws, noskipws) További manipulátorok találhatóak az iomanip fájlban, pl.: kitöltő karakter beállítása (setfill(<karakter>)), mező szélesség beállítása (setw(<szám>)) tizedes jegyek száma (setprecision(<szám>)) ELTE IK, Alkalmazott modul: Programozás 2:3 ELTE IK, Alkalmazott modul: Programozás 2:4 Feladat: Olvassunk be egy valós számot, majd írjuk ki 5 tizedes jegy pontosan egy 15 széles mezőben, amelyet pontokkal töltünk ki. int main() double nr; cout << "Kérek egy számot: "; cin >> nr; cout << right << fixed << setfill('.') << setw(15) << setprecision(5) << nr << endl; // formázás beállítása, majd kiírás Végjelig történő feldolgozás Amennyiben tetszőleges számú adatot akarunk elemenként feldolgozni, az olvasást végezhetjük egy lezáró adatig, úgynevezett végjelig A végjelig történő feldolgozásban a végjel általában már nem kerül feldolgozásra, ezért mindig ellenőriznünk kell, hogy nem a végjelet olvastuk-e be, pl.: while ( ) // olvasó ciklus cin >> data; // olvassuk a következő adatot if (data == ) // ha az adat a végjel break; // kilépünk a ciklusból // különben feldolgozzuk az adatot ELTE IK, Alkalmazott modul: Programozás 2:5 ELTE IK, Alkalmazott modul: Programozás 2:6 1

Végjelig történő feldolgozás Az ellenőrzés egyszerűsíthető az előreolvasási technika segítségével, ekkor már a ciklus előtt beolvassuk az első adatot a következő adatot a ciklusmag végén olvassuk, így a ciklusfeltétel ellenőrzése rögtön követi azt cin >> data; // előreolvasás while (data!= ) // amíg nem értünk a végjelhez // feldolgozzuk az adatot cin >> data; // olvassuk a következő adatot Feladat: Adjuk meg a bemenetről olvasott egész számok között hány páros szám található. A számsorozatot 0-val zárjuk. számlálás programozási tételt használunk, a szám páros, ha kettővel osztva 0-t ad maradékul a 0 a végjel karakter, amit már nem veszünk figyelembe előreolvasási technikát alkalmazunk int main() int nr; int c = 0; // számláló ELTE IK, Alkalmazott modul: Programozás 2:7 ELTE IK, Alkalmazott modul: Programozás 2:8 cout << "Kérem a számokat: "; cin >> nr; // előreolvasás while (nr!= 0) // a 0-val kilépünk if (nr % 2 == 0) // ha a szám páros c++; // növeljük a számlálót cin >> nr; // olvassuk a következő számot cout << "A számok közül " << c << " volt páros." << endl; Adatfolyamok hibakezelése Az adatfolyamok állapotellenőrzésére több művelet áll rendelkezésünkre a good() művelet megadja, hogy az adatfolyam konzisztens állapotban van-e és elérhető a fail() művelet megadja, hogy hiba történt-e az adatfolyamban az eof() művelet megadja, hogy az adatfolyamnak vége van-e a clear() művelet törli az adatfolyam hibás állapotát továbbá minden beolvasás (>>, getline) visszatérési értéke felhasználható állapotfelmérésre ELTE IK, Alkalmazott modul: Programozás 2:9 ELTE IK, Alkalmazott modul: Programozás 2:10 Adatfolyamok hibakezelése Pl.: int num; cin >> num; // megpróbálunk számot beolvasni if (cin.fail()) // ha sikertelen volt a művelet cout << "A megadott érték nem szám!"; else cout << "A beolvasás sikeres!"; // ugyanez: if (cin >> num) // sikeres volt a beolvasás cout << "A beolvasás sikeres!"; else cout << "A megadott érték nem szám!"; Feladat: Írjuk ki egy számnak a rákövetkezőjét. Ha nem számot adott meg a felhasználó, lépjünk ki. int main() int nr; cout << "Kérek egy egész számot: "; if (cin >> nr) // ha be tudtuk olvasni cout << ++nr << endl; else // ha nem tudtuk beolvasni cout << "A megadott érték nem egész szám!" << endl; ELTE IK, Alkalmazott modul: Programozás 2:11 ELTE IK, Alkalmazott modul: Programozás 2:12 2

Adatfolyamok hibakezelése A hibás állapotot helyre kell állítanunk a clear() utasítással Amennyiben nem megfelelő adat kerül a bemenetre, a sikertelen beolvasás nem törli az adatot, csak jelzi a hibát a hibás adat átugrását az ignore(<karakterek száma>, <termináló karakter>) utasítással végezhetjük Pl.: if (cin.fail()) cin.clear(); // töröljük a hibajelzést cin.ignore(256, '\n'); // karakterek átugrása a sortörésig cin >> num; // megpróbálunk újra olvasni Feladat: Írjuk ki egy számnak a rákövetkezőjét. Ha nem számot ad meg a felhasználó, akkor kérjük be újra. egy ciklusban ellenőrizzük a beolvasást, töröljük az állapotot, és újra bekérjük a számot mivel azt ellenőrzést a beolvasás után végezzük, használhatunk előreolvasást int main() int nr; cout << "Kérek egy egész számot: "; cin >> nr; // előreolvasás ELTE IK, Alkalmazott modul: Programozás 2:13 ELTE IK, Alkalmazott modul: Programozás 2:14 while (cin.fail()) // ha sikertelen a beolvasás cout << "A megadott érték nem egész szám!" << endl; cin.clear(); // töröljük a hibajelzést cin.ignore(256, '\n'); // karakterek átugrása a sortörésig cout << "Kérek egy egész számot: "; cin >> nr; cout << ++nr << endl; Fájlkezelés Fájlkezelés során az adatfolyamot egy fájl biztosítja, amelybe ugyanúgy tudunk írni és olvasni adatok, mint a képernyő esetén, de olvasás esetén előre adott a tartalom az adatok különféle módon lehetnek eltárolva a fájlban, ilyen tekintetben a legegyszerűbb a szöveges fájl, de lehet bináris fájl, vagy összetettebb (pl. DOC, XML, PDF) ha az adatokat sorban olvassuk be, illetve írjuk ki, akkor szekvenciális fájlról beszélünk tudjuk, mikor van vége az állománynak, ugyanis minden fájl végén egy fájl vége jel (end of file: EOF), és le tudjuk kérdezni, hogy ezt sikerült-e beolvasni ELTE IK, Alkalmazott modul: Programozás 2:15 ELTE IK, Alkalmazott modul: Programozás 2:16 Fájltípusok A fájlok szolgálhatnak bemenetként, illetve kimenetként is általában egy fájlt egyszerre csak egy célra használunk, és ez megjelenik a forráskódban is, de lehetőség van felváltva írni, illetve olvasni egy fájlból A fájlkezelésben megkülönböztetjük a fizikai fájlt: a háttértáron, elérési útvonallal kapcsolt tartalom logikai fájlt: a fájl megjelenése a programkódban, lényegében egy adott típusú változó a logikai és fizikai fájlt a programban társítanunk kell C++-ban a szöveges fájlok kezelését az fstream fájl biztosítja, amely az std névtérben található Három logikai fájltípust használhatunk: bemeneti fájl: ifstream kimeneti fájl: ofstream be- és kimeneti fájl: fstream A fizikai fájl társítását és megnyitását az open(<fizikai fájlnév>) paranccsal végezhetjük, pl.: ifstream f; // f nevű logikai fájl f.open("adatok.txt"); // társítás és megnyitás ELTE IK, Alkalmazott modul: Programozás 2:17 ELTE IK, Alkalmazott modul: Programozás 2:18 3

A létrehozás és a megnyitás egyesíthető, ha közvetlenül megadunk egy fájlnevet, pl.: ifstream f("adatok.txt"); A megnyitásnál alapértelmezett tevékenységeket végez (pl. írás esetén ha nem létezett a fájl, létrehozza, ha létezett, törli a tartalmát), amelyeket felülírhatunk az üzemmód megadásával, úgymint hozzáfűzésre (ios::app), vagy csak megnyitás (ios::nocreate), stb. az üzemmódokat kombinálhatjuk is a operátorral ofstream f; // f nevű logikai fájl f.open("adatok.txt", ios::nocreate ios::app); // nem hozza létre, hozzáfűzi a tartalmat ELTE IK, Alkalmazott modul: Programozás 2:19 Fizikai fájlnévként karaktertömb (char[]) típusú adatokat adhatunk meg, amit lehet változó is Ha string típusú változóba szeretnénk bekérni a fájlnevet, akkor azt át kell alakítanunk a szöveg típusban található egy olyan függvény, amely karaktertömbbé alakítja a szöveget, ezt használjuk: <változónév>.c_str() ifstream file; // logikai fájl string fname; // egy string cin >> fname; // beolvassuk a stringet file.open(fname.c_str()); // a beolvasott fájlnevet próbáljuk megnyitni ELTE IK, Alkalmazott modul: Programozás 2:20 Ha nem sikerült a fájl megnyitása, az adatfolyam állapota hibás lesz, amely a fail()művelettel ellenőrizhető, és a clear() művelettel helyreállítható Pl.: f.open("data/bemenet.dat"); // megnyitás if (f.fail()) // ha nem sikerült megnyitni cout << "Nem sikerült megnyitni a fájlt!"; f.clear(); // állapot helyreállítása cout << "Kérek a fájlnevet: "; string fname; cin >> fname; f.open(fname.c_str()); Fizikai fájlt használat után be lehet zárni a close() utasítással a bezárás automatikusan megtörténik a blokk végén, de azért célszerű külön bezárást végezni, amint befejeztük a programban a fájl használatát (különösen írás esetén) bezárást követően a logikai fájlnevet újra használhatjuk másik fizikai fájl kezelésére ifstream input("adat.txt"); // adat.txt megnyitása input.close(); // adat.txt bezárása input.open("adat2.txt"); // adat2.txt megnyitása ELTE IK, Alkalmazott modul: Programozás 2:21 ELTE IK, Alkalmazott modul: Programozás 2:22 Bemeneti fájlból olvashatunk (>>, getline), kimeneti fájlba írhatunk (<<) olvasásnál célszerű mindig ellenőrizni a beolvasott adatot, illetve a fájl állapotát egyszerű adatok esetén a végjelig történő feldolgozást könnyű ciklusba foglalni, pl.: ifstream f("adatok.txt"); // megnyitás ellenőrzése while (f >> data) // amíg sikerül adatokat beolvasni // addig feldolgozzuk f.close(); // fájl bezárása ELTE IK, Alkalmazott modul: Programozás 2:23 Részletesebb ellenőrzést is végezhetünk, ha nem akarjuk megszakítani a fájlolvasást az első hiba esetén, pl.: f >> data; // beolvasás előreolvasással while (!f.eof()) // amíg nincs vége a fájlnak if (f.fail()) // sikertelen beolvasás f.clear(); // állapot törlése f.ignore(1024, '\n'); // adatok átugrása else // sikeres beolvasás, feldolgozzuk f >> data; // következő adat beolvasása f.close(); ELTE IK, Alkalmazott modul: Programozás 2:24 4

Feladat: Írjuk ki a képernyőre a szamok.txt fájlban tárolt egész számok összegét. bementi fájlt feldolgozzuk összegzés tételével bármennyi szám lehet a fájlban, ezért addig dolgozunk, amíg sikeres a beolvasás (egész számot olvastunk be) int main() int nr, sum = 0; ifstream f("szamok.txt"); // megnyitás else // ha sikerült while (f >> nr) // amíg sikerül adatot olvasnunk sum += nr; f.close(); // fájl bezárása cout << "A számok összege: " << sum << endl; if (f.fail()) // ha nem sikerült cout << "Rossz fájlnév!" << endl; ELTE IK, Alkalmazott modul: Programozás 2:25 ELTE IK, Alkalmazott modul: Programozás 2:26 Feladat: Határozzuk meg egy fájlban tárolt soroknak a hosszát, és írjuk a képernyőre. a fájlnevet kérjük be a felhasználótól, sikertelen esetben lépjünk ki a programból int main() string filename, line; ifstream f; cout << "Bemenő adatok fájlja: "; cin >> filename; f.open(filename.c_str()); if (f.fail()) // ha sikertelen cout << "Nem található a fájl!" << endl; return 1; // kilépés // ha sikeres: while(getline(f, line)) // egész sorok olvasása cout << line.length() << endl; // sor hossza f.close(); ELTE IK, Alkalmazott modul: Programozás 2:27 ELTE IK, Alkalmazott modul: Programozás 2:28 Feladat: Egy telkonyv.txt fájlban a következő formátumban vannak a sorok: vezetéknév keresztnév,cím,telefonszám. Írjuk ki az adatokat az uj_telkonyv.txt fájlba a következő formátumba: keresztnév vezetéknév,telefonszám (15 hosszan, jobbra igazítva), cím. feltételezzük, hogy a fájl létezik, és a formátuma helyes négy lépésben olvassuk be a sort négy szöveg változóba előreolvasási technikát használunk kiíráskor megfelelő manipulátorokkal (right, setw) módosítjuk a kimenetet int main() string sname, gname, addr, nr; ifstream phb("telkonyv.txt"); ofstream nphb("uj_telkonyv.txt"); // sor beolvasása 4 lépésben: getline(phb, sname, ' '); // olvasás az első szóközig, a szóköz karakter // elveszik getline(phb, gname, ','); getline(phb, addr, ','); getline(phb, nr); // olvasás a sor végéig ELTE IK, Alkalmazott modul: Programozás 2:29 ELTE IK, Alkalmazott modul: Programozás 2:30 5

while(phb.good()) // formázott kiírás: nphb << gname << " " << sname << ","; nphb << right << setw(15) << nr << ","; nphb << addr << endl; // következő sor beolvasása: getline(phb, sname, ' '); getline(phb, gname, ','); getline(phb, addr, ','); getline(phb, nr); phb.close(); nphb.close(); Szövegfolyamok A szövegfolyamok olyan adatfolyamok, ahol az írás és olvasás szövegen keresztül történik a memóriában típusa a stringstream, használatához szükséges az sstream fájl és az std névtér tetszőleges típusú változót írhatunk be (<<) és olvashatunk ki (>>, getline), a sorrend megmarad alkalmas olyan típuskonverziókat elvégezni, amik automatikusan nem történnek meg (pl. szöveg-szám) az str() művelet egyben, szövegként tudja kiadni a szövegfolyam tartalmát, míg az str(<szöveg>) kitörli a korábbi tartalmat, és a paraméterben megadottat helyezi be ELTE IK, Alkalmazott modul: Programozás 2:31 ELTE IK, Alkalmazott modul: Programozás 2:32 Szövegfolyamok Szám-szöveg konverzió esetén a szövegfolyam hasonló feladatot lát el, mint a korábbi itoa és atoi műveletek, amelyek csak karaktersorozatokkal tudnak dolgozni Pl. szám átalakítása szöveggé: int num; // num értéket kap stringstream converter; // az átalakítást szövegfolyammal végezzük converter << num; // behelyezzük a számot string output = converter.str(); // szövegként kapjuk meg a tartalmat // ugyanez: // converter >> output; Szövegfolyamok Pl. szöveg átalakítása számmá: int num; string input; cin >> input; // beolvassuk a számot szövegesen stringstream converter; converter << input; // behelyezzük a szövegfolyamba converter >> num; // megpróbáljuk kiolvasni számként if (converter.fail()) // ha sikertelen az átalakítás cout << converter.str() << " nem szám!"; // kiírjuk a szövegfolyam tartalmát ELTE IK, Alkalmazott modul: Programozás 2:33 ELTE IK, Alkalmazott modul: Programozás 2:34 Feladat: Írjuk ki egy számnak a rákövetkezőjét. Ha nem számot adott meg a felhasználó, lépjünk ki. a bemenetet nem rögtön számként, hanem szövegként olvassuk be használjunk szövegfolyamot a konverzió elvégzésére, csak akkor végezzük el a növelést, ha sikeres a konverzió int main() string textinp; int numinp; stringstream sstr; // szövegfolyam cout << "Kérek egy számot: "; cin >> textinp; sstr << textinp; // beírjuk a szöveget sstr >> numinp; // kiolvasunk egy számot if (sstr.fail()) // ha lehetett konvertálni cout << sstr.str() << " nem szám!"; else // ha nem lehetett konvertálni cout << ++numinp << endl; ELTE IK, Alkalmazott modul: Programozás 2:35 ELTE IK, Alkalmazott modul: Programozás 2:36 6

Egyszerű tömbök A C++ biztosít számunkra egy egyszerű tömb típust, amelyen az egyedüli értelmezett művelet az indexelő operátor használata int t[10]; // 10 méretű tömb létrehozása cin >> t[0]; // tömb első eleme értéket kap ezzel a tömbbel több probléma is felmerül: nem lehet lekérdezni a méretét (korlátozottan használható a sizeof operátor erre a célra, de ez nem praktikus) csak konstans adható meg méretként nem lehet a méretét futás közben megváltoztatni Intelligens tömbök A C++ ezért biztosít egy speciális tömb típust vector néven, amely a korábbi hiányosságokat pótolja használatához szükséges a vector fájl és az std névtér létrehozásához speciálisan kell megadnunk az elemtípust, illetve a méretet (amely lehet változó, illetve 0 is, csak negatív szám nem), pl.: vector<int> v1(10); // 10 elemű egész tömb int size = 5; vector<string> v2(size); // 5 elemű szövegtömb a méretet nem kötelező megadni, ekkor egy 0 méretű tömböt hoz létre, pl.: vector<int> v3; // 0 elemű egész tömb ELTE IK, Alkalmazott modul: Programozás 2:37 ELTE IK, Alkalmazott modul: Programozás 2:38 Intelligens tömbök mindig ismeri a méretét, és ez lekérdezhető futás közben átméretezhető, akár teljesen ki is üríthető fontosabb műveletei: elem lekérdezés, módosítás: <változónév>[<index>] méret lekérdezése: <változónév>.size() kiürítés: <változónév>.clear() átméretezés: <változónév>.resize(<új méret>) új elem behelyezése a tömb végére (és egyúttal a méretnövelése): <változónév>.push_back(<érték>) utolsó elem kivétele (és egyúttal a méret csökkentése): <változónév>.pop_back() Szövegfolyamok Pl. számok sorrendjének megfordítása: vector v; // itt v.size() == 0 int nr, d; cin >> nr; for (int i = 0; i < nr; i++) cin >> d; v.push_back(d); // vektor bővítése // itt v.size() == nr for (int i = v.size(); i > 0; i--) d = v.pop_back(); // vektor csökkentése cout << d << endl; // itt v.size() == 0 ELTE IK, Alkalmazott modul: Programozás 2:39 ELTE IK, Alkalmazott modul: Programozás 2:40 Feladat: Olvassunk be valós számokat a bemenetről amíg 0-t nem írunk, majd adjuk meg az átlagnál nagyobb elemek számát. előbb egy összegzést (az eredményt osztjuk a számok számával), majd egy számlálást kell végeznünk ehhez azonban el kell tárolnunk az elemeket mivel nem tudjuk az elemek számát, olyan adatszerkezet kell, amelynek mérete növelhető futás közben, tehát vector-t kell használnunk, és annak a push_back függvényét beolvasáskor érdemes ellenőrizni, hogy számot kaptunk-e #include <vector> // használjuk a vector-t int main() vector<float> v; // float típusú vector, alapból 0 hosszú lesz float act; while (cin >> act && act!= 0) // amíg számot kaptunk, amely nem a végjel v.push_back(akt); // berakjuk a végére ELTE IK, Alkalmazott modul: Programozás 2:41 ELTE IK, Alkalmazott modul: Programozás 2:42 7

float avg = 0; // összegzés for (int i = 0; i < v.size(); i++) avg += v[i]; // kiolvasunk minden elemet avg /= v.size(); // mérettel osztunk int c = 0; // számlálás for (int i = 0; i < v.size(); i++) if (v[i] > avg) c++; cout << "Az átlagnál " << c << " elem nagyobb." << endl; Mátrixok Mivel egy tömb tetszőleges típusú elemek sorozata, az elemtípus maga is lehet tömb, így létrehozhatjuk tömbök tömbjét, azaz a mátrixot a tömb dimenziószáma az egymásba ágyazás mértéke az egy dimenziós tömbök a vektorok, a két, illetve magasabb dimenziósok a mátrixok int t[10][5]; // egy 10, 5 elemű egészekből álló tömbből álló // tömb, vagyis 10x5 méretű egész típusú mátrix cin >> t[0][3]; // az első sor negyedik elemének bekérése ELTE IK, Alkalmazott modul: Programozás 2:43 ELTE IK, Alkalmazott modul: Programozás 2:44 Feladat: Adott 10 tanuló egyenként 5 jeggyel, állapítsuk meg a legjobb átlaggal rendelkező tanulót. ehhez használjunk egy mátrixot, kérjük be a jegyeket egyenként határozzuk meg minden hallgatóra az átlagot, majd abból keressük meg a maximumot, tehát több programozási tételt is alkalmazzunk a megoldáshoz int main() int m[10][5]; // jegyek mátrixának létrehozása float avg[10]; // átlagok tömbjének létrehozása ELTE IK, Alkalmazott modul: Programozás 2:45 for (int i = 0; i < 10; i++) for (int j = 0; j < 5; j++) cout << i+1 << ". tanuló " << j+1 << ". jegye: "; cin >> m[i][j]; // jegyek beolvasása // összegzés hallgatónként: for (int i = 0; i < 10; i++) avg[i] = 0; for (int j = 0; j < 5; j++) avg[i] += m[i][j]; avg[i] /= 5; // átlagot számítunk ELTE IK, Alkalmazott modul: Programozás 2:46 int max = 0; // maximumkeresés az átlagok vektorán for (int i = 1; i < 10; i++) if (avg[i] > avg[max]) max = i; cout << "Legjobban a(z) " << max+1 << ". tanuló teljesített." << endl; Mátrixok A vector típus is felhasználható mátrixok létrehozására a létrehozása kissé körülményes, mivel csak a külső tömb mérete adható meg közvetlenül, a belső tömböket külön kell átméretezni pl. egy 10 5-ös egészmátrix létrehozása: vector<vector<int> > m(10); // külső tömb létrehozása for (int i = 0; i < m.size(); i++) m[i].resize(5); // belső tömbök létrehozása ezután az indexelés a megszokott módon történik, pl.: m[0][0] ELTE IK, Alkalmazott modul: Programozás 2:47 ELTE IK, Alkalmazott modul: Programozás 2:48 8

Feladat: Adott 10 tanuló egyenként 5 jeggyel, állapítsuk meg a legjobb átlaggal rendelkező tanulót. használjunk intelligens vektor alapú mátrixot int main() vector<vector<int> > m(10); // sorok létrehozása for (int i = 0; i < m.size(); i++) m[i].resize(5); // oszlopok létrehozása // innentől használható a mátrix vector<float> avg(m.size()); // átlagok tömbje for (int i = 0; i < m.size(); i++) for (int j = 0; j < m[i].size(); j++) cout << i+1 << ". tanuló " << j+1 << ". jegye: "; cin >> m[i][j]; // jegyek beolvasása // összegzés soronként: for (int i = 0; i < m.size(); i++) avg[i] = 0; for (int j = 0; j < m[i].size(); j++) avg[i] += m[i][j]; avg[i] /= m[i].size(); // átlagot számítunk ELTE IK, Alkalmazott modul: Programozás 2:49 ELTE IK, Alkalmazott modul: Programozás 2:50 int max = 0; // maximumkeresés az átlagok vektorán for (int i = 1; i < avg.size(); i++) if (avg[i] > avg[max]) max = i; cout << "Legjobban a(z) " << max + 1 << ". tanuló teljesített." << endl; ELTE IK, Alkalmazott modul: Programozás 2:51 9