44
Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk [email protected] D-2.620 1

Programozási Nyelvek (C++) Gyakorlat Gyak 03

  • Upload
    lew

  • View
    49

  • Download
    3

Embed Size (px)

DESCRIPTION

Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk tmark @ caesar.elte.hu D-2.620. 1. Kódelemzés. Feladat: Olvassunk be betüket a sabványos bemenetről (a – z), és írjuk ki a nagybetűs párjukat (A – Z). Különleges karakterek, nagybetűk helyben maradnak, angol abc-vel dolgozunk. - PowerPoint PPT Presentation

Citation preview

Page 1: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Programozási Nyelvek (C++) Gyakorlat

Gyak 03.

Török Márk

[email protected]

D-2.620

1

Page 2: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Feladat:Olvassunk be betüket a sabványos bemenetről (a – z), és írjuk ki a nagybetűs párjukat (A – Z).Különleges karakterek, nagybetűk helyben maradnak, angol abc-vel dolgozunk.

Page 3: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Tömbök

Page 4: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Konstansokról

• Nézzünk egy példát:– strlen implementálása:

int strlen( char* s ){

char *p = s;while ( *p != '0' ){

++p;} // hello world0, előre zavarom a p-t.return p - s; // két pointer különbsége az adott szó hossza.

}

4

Page 5: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Konstansokról

• Mi van akkor, ha:

int strlen( char* s ){

char *p = s;while ( *p = '0' ) // hiba lehetőség!{

++p;}return p - s;

}

5

Page 6: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Konstansokról

• Javítsuk:int strlen( const char* s ){

const char *p = s; // csak együtt lehetnek!while ( *p = '0' ) // így már szemantikai

hiba!{

++p;} return p - s;

}

6

Page 7: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Áttekintés:– Kezdjünk egyből C++-vel!– Ha egy C++ programot írunk, érdemes a biztonságra

törekedni.• Azaz, kerüljük, hogy egyszerre megírjuk az egészet, és csak

utána fordítunk!• Részenként kell csinálni! (és úgy fordítani!)

– Ezek a lépések:1. Elso lépésként megnézzük, hogy a stdinputot másolja át a stdoutputra!

2. Második lépésként nézzük meg, hogy felismerie a kisbetűt.

3. Majd harmadik lépésként alakítsuk a felismert kisbetűket nagybetűssé!

Page 8: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

#include <iostream>

int main() {

char ch;std::cin >> std::ios_base::noskipws;while ( std::cin >> ch ){

std::cout << ch;}return 0;

}

Page 9: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás:#include <iostream>using namespace std;

int main() {

char ch;while (cin >> noskipws >> ch) {

cout << …(???)}

}

– noskipws: io-manipulátor, nem ugorja át a whitespaceket (space, tab,…), ennek testvére a skipws, mely átugorja azokat.

Page 10: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Fordul! Yeehaaa!• Kisbetűk felismerése a feladat!

Page 11: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <iostream>

int main() {

char ch;std::cin >> std::ios_base::noskipws;while ( std::cin >> ch ) {

if ( 'a' <= ch && ch <= 'z') // #1{

std::cout << ch + 'A' - 'a'; // #2} else {

std::cout << ch;}

}return 0;

}

Page 12: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• #1 Kérdés: Működik-e char-ok között a <= operator? Mivel mindegyik int-re konvertálódik, így az ascii kódok között történik meg a <= vizsgálat!

• #2 Kérdés: Hogyan konvertáljuk a karaktereket nagybetűvé?Mivel ascii-val dolgozunk, ezért ch + 'A' - 'a'

Page 13: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• int-ek kerülnek kiírásra, mivel a + és - szintén nincs értelmezve a char-ok között!

• ascii kód íródik ki, ahelyett, hogy char érték íródott volna ki!

Page 14: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <iostream>

int main() {

char ch;std::cin >> std::ios_base::noskipws;while ( std::cin >> ch ) {

std::count << 'a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch;

}return 0;

}

Page 15: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Mi történt?– A kiértékelés miatt precedenciaproblémák

vannak!

Page 16: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <iostream>

int main() {

char ch;std::cin >> std::ios_base::noskipws;while ( std::cin >> ch ) {

std::count << ('a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch);

}return 0;

}

Page 17: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Továbbra is számok íródnak ki! Meglepő módon most már a betűk helyett is számok íródnak ki!

• T1 T2 ==> T• Fordítási időben meg kell mondania, hogy melyik kiíró-

operátort válassza meg! A fordítónak fordítás alatt tudnia kell, hogy milyen a kifejezés típusa!

• Itt: int op char => int

Page 18: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Promotion rules:– short, char => int– float => double– double => long double

• Odafelé jól mentek a dolgok, maguktól mentek a konverziók!

• Visszafelé már nem!

Page 19: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Megoldások:– char(i), ha i : integer, akkor i-t char-ra

konvertáljuk.– static_cast<char>(i) (Később)– char ch = i;

Page 20: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <iostream>

int main() { char ch; std::cin >> std::ios_base::noskipws; while ( std::cin >> ch ) { std::count << char('a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch); } return 0;}

Page 21: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Más lehetőség:– Saját toupper metódus írása!

• Amit egyszer már megírtak, azt ne írjuk meg mégegyszer!– Beépített toupper metódus használata

Page 22: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Írjunk olyan utility-t, ami úgy működik, mint egy unixparancs.

• Ha nem adunk paramétert, akkor stdinput/outputot használja, ha adunk paramétert, akkor azt, mint fájlt akarja használni!

Page 23: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

#include <iostream>

int main(int argc; char *argv[]){ ...}

Page 24: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

#include <iostream>

void toupper(std::istream&, std::ostream&);

int main( int argc; char *argv[] ){ if ( argc < 2 ) { toupper(std::cin, std::cout); }}

Page 25: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Akár van fájl, akár nincs, ugyanazt csinálom, ezzel megóvom magamat a dupla munkától!

• az istream, ostream osztályoknak a copyconstruktora private, hogy ne lehessen másolni, így mindig referencia szerint adom át öket paraméternek.

Page 26: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <fstream>#include <iostream>

void toupper(std::istream&, std::ostream&);

int main( int argc; char *argv[]){ if ( argc < 2 )

{toupper(std::cin, std::cout);

}else{

// folyt.}return 0;

}

Page 27: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

for ( int i=1; i < argc; ++i ){

// Meg kell nyitni a fájlt! ifstream inp(argv[i]);if ( !inp ){

std::cerr << "Can't open" << argv[i] << std::endl;

}else{

toupper(inp, std::cout);}

}

Page 28: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Kérdés: Kell-e close-t mondanom?– Amikor a zárójelet becsukom, akkor az

ifstream destruktora meghívódik!

Page 29: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Feladat:Számoljuk meg, hogy a bemeneten hány sor volt. (Sorvége-jel: ‘\n’)

Page 30: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés#include <fstream>#include <iostream>

void lines(std::istream&, std::ostream&);

int main( int argc; char *argv[]){ if ( argc < 2 )

{lines(std::cin, std::cout);

}else{

// folyt.}return 0;

}

Page 31: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

for ( int i=1; i < argc; ++i ){

ifstream inp(argv[i]); if ( !inp )

{std::cerr << "Can't open" << argv[i] <<

std::endl;}else{

lines(inp, std::cout);}

}

Page 32: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Egy adott karakter előfordulása egy egyszerű számlálás!

Page 33: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

void lines( std::istream& inp, std::ostream& outp ){

int cnt = 0;char prev = '\n';char curr; while ( std::cin.get(curr) ){

cnt = f(cnt, prev, curr); prev = curr;

}}

Page 34: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

int f( int cnt, char prev, char curr ) // warning!{

if ( '\n' == prev ){

++cnt;}return cnt;

}

Page 35: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

int f( int cnt, char prev, char ) // így már nem!{

if ( '\n' == prev ){

++cnt;}return cnt;

}

Page 36: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Javítás:void lines( std::istream& inp, std::ostream& outp ){

int cnt = 0;char prev = '\n';char curr; while ( std::cin.get(curr) ){

cnt += '\n' == prev;prev = curr;

}}

Page 37: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás:#include <iostream>

int main() {

int ls = 0;char c;while ( std::cin >> std::noskipws >> c) {

if (c == ‘\n’) {

ls += 1;}

}std::cout << ls << std::endl;return 0;

}

Page 38: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás: más út

#include <iostream>

int main() {

int ls = 0;char c;while (std::cin >> std::noskipws >> c) {

ls = (c == ‘\n’ ? ls + 1 : ls);}std::cout << ls << std::endl;return 0;

}

Page 39: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Kimenet:

almaszilvactrl-Deredmény: 2

almaszilva ctrl-Deredmény: 1

Page 40: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Feladat:Írjuk át úgy a programot, hogy ne az ‘\n’ karaktereket keressük, mert az utóbbi esetben hibás a végrehajtás.

Page 41: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás:

int f ( char prev, int ls) {

return prev == ‘\n’ ? ls + 1 : ls;}

char c, prev;while ( std::cin >> std::noskipws >> c) {

ls = f(prev, ls);prev = c;

}

Page 42: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

• Feladat:Szavak számának a számolása.alma (1) „ „ szilva (2) …

Page 43: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás:

int f (char prev, char c, int ls) {

return ( prev == ‘\n’ || prev == ‘\t’ || prev == ‘ ‘)&& c != ‘\n’ && c != ‘\t’ && c != ‘ ’ ? ls + 1 :

ls;}

Page 44: Programozási Nyelvek (C++) Gyakorlat Gyak 03

Kódelemzés

•Megoldás: Más út

bool isWS(char c) {

…}