C++ be- és kimenet: cout, cin (iostream)

C++ be- és kimenet: cout, cin (iostream)

Anime illusztráció: C++ be- és kimenet – programozó lány, monitor előtt; cout « és cin » hangulatban

c++ alapok

C++ be- és kimenet alapjai

Ebben a leckében a C++ be és kimenet alapjait tanuljuk meg: hogyan írunk ki dolgokat a képernyőre std::cout-tal és hogyan olvasunk be adatokat a billentyűzetről std::cin-nel az iostream segítségével. Végigmegyünk azon, mi a különbség a '\n' és a std::endl között, mikor miért jobb az egyik, miért harapja le a szóköz utáni részt a >> és hogyan oldja meg ezt az std::getline + std::ws / cin.ignore. 

A lecke célja, hogy a C++ be- és kimenet rutinszerű legyen: tudj számot és teljes nevet beolvasni, szépen formázva kiírni (pl. két tizedessel), és alap validitást csinálni (hibás input esetén törölni a hibajelzőt és kiüríteni a sort). A végén rövid, gyakorlati mini feladatokkal zárunk, hogy azonnal be is gyakorold. 

Kiírás (std::cout)

Gyors kezdés: szöveg, szám, kifejezés

C++ be- és kimenet: cout példák – változó értékének és kifejezésnek a kiírása Dev-C++ konzolra ('Szamoljunk', x és 2*x)

Mi az az std?

A standard library (szabványkönyvtár) dobozcímkéje, hivatalosan névtér (namespace). A könyvtárban rengeteg név van (cout, cin, string, vector ...), és hogy ne ütközzenek a te saját neveiddel, előtte kiírjuk, hogy std:: - így jelezzük a fordítónak, hogy ezt a nevet a standard könyvtárból szeretném. 

Mi az a cout

A cout egy előre elkészített objektum a szabványkönyvtárban, amely a szabványos kimenetre (konzol/ablak) ír. Console output. Nekünk most elég annyi, hogy ez az a dolog, amivel kiírunk valamit a képernyőre. 

Mi a <<?

A << "folyamba helyezés" operátora. Jelentése: tedd be ezt az adatot a kimeneti folyamba, balról jobbra dolgozik és láncolható: 

C++ be- és kimenet: std::cout több hívással, std::endl és szöveg kiírása – láncolás nélkül.

Mind a két esetben ugyanaz lesz a kiírás - nem kell külön sorba újra kiíri az std::cout sort, elég csak ezzel << az operátorral felsorolni és a legvégét lezárni egy pontosvesszővel. 

Új sor: std::endl vs 'n'

Mit csinálnak?

  • '\n' - egy új sor karakter. Simán sortörést jelent
  • std::endl sort tör és mellette kiüríti a kimeneti puffert is. Ez akkor fontos, ha azonnal látni akarod a kiírást. 

Mikor melyiket érdemes használni?
Alapból használd az '\n' -t, mert gyorsabb, de ha biztosra akarsz menni, hogy a szöveg rögtön megjelenjen, akkor std::endl

Bemenet: std::cin

Gondolj az std::cin-re úgy, mint egy futószalagra (pufferre), amin karakterek érkeznek. 

  • A >> operátor a whitespace-ig (szóköz/Enter/Tab) olvas egy darabot.
  • A getline Enterig olvas teljes sort (szóközökkel együtt)
  • A get egy darab karaktert vesz le - akár szóközt vagy Entert is

Hova tegyük az adatot? 

Szöveget std::string-be, számot int/double-ba teszünk. A változónév lehet betű, szám, alsóvonás, de nem kezdődhet számmal és nem lehet kulcsszó (pl. int, double, return stb.)

Mi történt itt? Csak a vezetéknevet vette be, mert a >> az első szóközig olvasott csak. Ha szeretnénk mind az egész sort megjeleníteni, akkor a megoldás az std::getline lesz

Számok beolvasása (int, double)

Az >> operátor szóközig olvas és rögtön megpróbálja átalakítani az értéket a cél típusára

Több adatot egymás után is bekérhetsz egy sorban - a >>-t mindegy, hogy szóköz, tab, vagy Enter választja el 

Szóköz és Enter csapdák: std::ws és std::cin.ignore

Képzeld el a bemenetet (stdin) egy futószalagnak. Az >> operátor szóközig olvas (szóköz, Enter, Tab = whitespace), a soron következő whitespace-t pedig rajtahagyja a szalagon. Ezért van az, hogy szám beolvasása után egy std::getline néha üres sort kap: az előző Enter még ott csücsül elől. 

Két egyszerű eszközünk van erre: 

1.) std::ws - "whitespace-porszívó"

Az std::ws felfalja az elején álló whitespace-eket (Entert is)

Mikor jó? 
Ha >> után egyból sorbeolvasás (getline) jön vagy ha nem baj, hogy minden kezdő szóközt is elnyel (pl. a felhasználó véletlenül beütött pár space-t)

 

2. std::cin.ignore

Az ignore kifejezetten arra való, hogy eldobjunk karaktereket a puffer elejéről. Klasszikus minta: dobt el a teljes sor maradékát (az Enterig), aztán olass getline-nel

Mikor jó? 

Ha biztosan a sor végét szeretnéd kidobni (pl. >> után jön még egy getline, vagy ha a menüben/űrlapon szeretnéd letisztítani a sort egy rövid karakteres input után.  

C++ be- és kimenet: cin.ignore() és std::getline() példa – az Enter eldobása, hogy ne kapjunk üres sort

Mi történik? 

Nem a számot dobjuk el, hanem azt, ami utána marad a pufferben - tipikusan az Entert, esetleges szóközöket, maradék karaktereket. Mindig van eldobnivaló amikor >>-val olvasol, mert a >> csak a tokenig eszik, a leválasztó (whitespace, '\n') bent marad. 
Tehát: írsz valamit, Entert nyomsz: akkor beírod: 5 + Enter
A pufferbe kerül ['5'] ['\n']
beírod: int darab;
std::cin >> darab //megeszi az '5'-öt, a pufferben marad: ['\n'] 
Ha most rögtön jönne a std::getline(...), az az első karakterig a sor végéig olvas. De az első karakter már a '\n', ezért üres sort kapsz. Ezeket ignoráljuk. Eldob mindent a sor végéig, beleértve az '\n'-t is, így az std::getline a következő sort kapja meg, nem az üreset. 

Ha nagyon röviden kéne megfogalmazni: >> meghagyja a leválasztót, a maradékot el kell dobni. std::getline sorig olvas, ha elsőnek '\n' van, üres lesz

Mikor használj std::ws-t és mikor std::cin.ignore-t?

Ha csak Enter maradt elől -> std::ws. Elég csak egy whitespace kiszippantása.
Ha a sorban maradék szöveg is lehet, akkor használd az ignore(..., '\n') -t

 

Puskasor - C++ be és kimenet

  • std::cout << ... → kiírás. Láncolható. '\n' gyors newline, std::endl newline + puffer ürítés.

  • std::cin >> x → whitespace-ig olvas és konvertál 

  • std::getline(std::cin, s) → teljes sor az Enterig (szóközökkel együtt).

  • >> után getline előtt: ignore(..., '\n') vagy getline(std::cin >> std::ws, s).

 

Mi jön ezután?

A következő fejezetben a változókról és típusokról beszélünk (egész, valós, karakter, szöveg; névadás, alapértelmezett értékek, típuskonverziók, const), hogy a most beolvasott értékeket jól tudjuk tárolni és számolni velük.

Lecke vége: anime lány V-jelet mutat, laptopon Visual Studio Code, mellette bögre tea és alvó cirmos macska, konfettivel.

Ha máshol szeretnéd folytatni a C++ tanulást, itt válogathatsz

C++ alapok: main függvény, programváz

C++ alapok: main függvény, programváz

Anime programozólány C++ kóddal – c++ main függvény (belépési pont) illusztráció

C++ alapok

C++ main függvény

Mielőtt belevágnánk a C++ témába, rakjunk rendet: mi az a forrásfájl, a C++ main függvény, hogyan néz ki a programváz, mik azok a headerek (#include <...>) és mit ad a C++ stardard library.
Ha a környezeted még nincs kész, itt a két útmutató hozzá:
– Dev-C++ telepítés, beállítás
– Dev-C++ használata (projekt, fájl, futtatás)
A Dev-C++-t innen is le tudod tölteni: Embarcadero hivatalos oldala

A legkisebb, már hasznos C++ program

C++ main függvény – Dev-C++ konzol kimenet (Hello, C++)

A C++ main függvény mindig int típussal tér vissza A return 0; státuszkód: az operációs rendszernek üzen, hogy a program sikeresen lefutott.
Az #include <iostream> fejléccel kapjuk meg a be-/kimeneti eszközöket (pl.: std::cout)

Mi történt, amikor lefuttattad a "Hello, C++"-t?

1. Előfeldolgozás - #include

Az #include <iostream> olyan, mintha a fordítás előtt a fordító bemásolná az iostream fejléc tartalmát a fájlod elejére. Ez a fejléc adja a std::cout (kiírás), std::cin (beolvasás) neveit. Ha ezt elhagyod, a fordító nem tudja, mi az a std::cout -> hibára fog futni. 

2. Fordítás - ellenőrzés és gépi kód

A fordító végigmegy a kódon: jók-e a szintaktikai szabályok (pontosvessző, kapcsos zárójelek, létező nevek stb.) Ha rendben, a kódból objektumkód lesz.

3. Linkelés - összerakás

A linker hozzákapcsolja a programodhoz a szükséges kész elemeket a standard libraryból (pl. ami a std::cout mögött dolgozik). Ebből lesz a futtatható fájl. 

4. Futtatás - indul a main()

A programod mindig a main() függvény elején indul. Soronként lefutnak az utasítások: 

kiírja a szöveget

majd a return 0; - ezzel státuszkódot ad vissza az operációs rendszernek. Ha egyezik, azaz 0, akkor siker, ha nem 0, akkor valami gond adódott. A Dev-C++ a futás végén azt írta: "Process exited with return value 0" -> a program rendben lefutott

 

C++ main függvény előtt: include és a standard library

1. #include <...>

Előre megírt eszközök neveit hozod be, (most iostream az I/O-hoz). Mit érdemes ehhez még megjegyezni? 
iostream - kiírás a képernyőre (cout), beolvasás a billyentyűzetről (cin)
string - szöveg tárolásához, pl.: neveknél, országkódoknál, fájlneveknél. Például:
           #include <string> 
           std::string nev = "Kata";
           nev += " Kovacs";           //összefűzés

vector - rugalmas tömb, mely nőhet, csökkenhet. Akkor használd, ha nem tudod, hány elemed lesz (pl. beolvasás fájlból)

limits - a std::numeric_limits családot adja. Gyakran cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n') mintához használjuk, amikor a bemeneti pufferből ki akarjuk dobni a maradékot (például egy szám után maradt entert)

iomanip - szép kiírás, oszlopszélesség, tizedesek száma, hex/dec. stb. Táblázatos kiírásoknál használd, pénzösszeg formázásánál, statisztikánál

cmath - matekos függvényeknél hasznos, sqrt, pow, abs, sin stb.

fstream - fájlolvasáshozs és -íráshoz (ifstream, ofstream). Akkor használd, ha a feladat fájlból kér adatot. 

algorithm - rendezésnél, min/max keresésnél, darabszámolásnál hasznos: sort, min_element, max_element, count_if stb.

set - elemek gyűjtéséhez hasznos, duplikátum nélkül, automatikusan elrendezve

map - képzeld el, hogy vannak címkés dobozaid. Minden doboz címkéje a kulcs, a dobozban levő tartalom pedig az érték. A kulcsok egyediek, egy címke csak egyszer szerepelhet, pl HUN - országkód, érték: hány magyar versenyző van. Akkor használd, ha össze akarsz kapcsolni két dolgot: a kulcsot az értékkel, pl.: nemzetet - darabszámmal, rajtszámot - versenyzői adatokkal

sstream - ha egy sorban több adat van és kényelmesen szét szeretnéd bontani

cctype - karaktervizsgálat. Bemenet ellenőrzésnél (szám-e), normalizálásnál (kisbetűsítés)

array - fix méretű, "biztonságosabb" tömb, ha tényleg fix a méret. Például tudod, hogy 5 elemet tartalmaz és nem kell nőnie. 

Fontos, hogy csak az include-old, amit tényleg használsz, hogy a jód tisztább és a fordítás gyorsabb legyen. Ezekről majd később lesz szó bővebben, most csak néhányat kiemeltem, ami fontos lehet. 

2. mi az az std:: ?

A standard library elemei az std névtérben vannak: std::cout, std::cin, std::string, std::vector ...
Kezdőként inkább írd ki az std::-ot, egyértelműbb és elkerülöd az ütközéseket.

 

C++ main függvény

Minden C++ program kötelező belépési pontja a main() függvény, itt indul az egész programozás.
A függvény négy részből áll:

1. Visszatérési típus - amikor egy függvény lefut, valamit visszaadhat annak, aki meghívta. Ennek a "valaminek" előre megmondjuk a típusát - ez a visszatérési típus. Lehet:

      • int > egész számot ad vissza (hányat dobtál a dobókockával?)
      • double > valós számot ad vissza (mennyi volt az átlagpontszám?)
      • bool > igaz/hamis értéket ad vissza (páros szám?)
      • std::string > szöveget ad vissza (köszönés szövege)
      • void > nem ad vissza értéket, csak elvégez valamit (csak történik valami, nem hoz semmit vissza, pl Kapcsold fel a villanyt)

Példa:   
int duplaz(int x) {
return 2 * x;
}
//visszatérünk az x kétszeresével (egész szám)

bool paros(int n) {
return n % 2 == 0;
}
//n: egy változó. A függvény ide kapja meg a számot, amit ellenőriznünk kell. 
% - maradékos osztás. pl. a % b = maradék. ha 8%2=0 (nem marad semmi, tehát páros). ha 13%2=1
== egyenlőségvizsgálat. Kérdés a gépnek: egyenló-e a jobb és a bal oldal. n%2 == 0 akkor igaz, ha az osztás maradéka 0

#include <string>
std::string udvozol(const std::string& nev) {
return "Szia, " + nev + "!";
}

#include <iostream>
void kiirSzoveg(const std::string& s) {
std::cout << s << '\n';
}
//void - nincs visszatérési érték. A függvény csak elvégez valamit (kiír valamit itt a képernyőre és kész). 
kiirSzoveg - a függvény neve

Mit tudsz most?

  • mi a forrásfájl és a header, hogyan hozunk be eszközöket az #include <...> - val
  • mi a standard library és az std:: névtér szerepe
  • a main() a belépési pont; int státuszkódot ad vissza (0=siker)

Szuper munka!

 

Ha a C++ main függvény és a programváz világos, ugorjunk tovább az adatok kiírására és beolvasására:

➡️ Következő lecke: C++ be- és kimenet – cout, cin (iostream) »
⬅️ Vissza az áttekintő oldalra: C++ alapok – összes lecke »

 

Lecke vége: anime lány V-jelet mutat, laptopon Visual Studio Code, mellette bögre tea és alvó cirmos macska, konfettivel.