Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

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

Hasonló előadás


Az előadások a következő témára: "Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk D-2.620 1."— Előadás másolata:

1 Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk D

2 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.

3 Tömbök

4 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

5 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

6 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

7 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é!

8 Kódelemzés #include int main() { char ch; std::cin >> std::ios_base::noskipws; while ( std::cin >> ch ) { std::cout << ch; } return 0; }

9 Kódelemzés Megoldás: #include 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.

10 Kódelemzés Fordul! Yeehaaa! Kisbetűk felismerése a feladat!

11 Kódelemzés #include 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; }

12 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'

13 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!

14 Kódelemzés #include 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; }

15 Kódelemzés Mi történt? –A kiértékelés miatt precedenciaproblémák vannak!

16 Kódelemzés #include 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; }

17 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

18 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!

19 Kódelemzés Megoldások: –char(i), ha i : integer, akkor i-t char-ra konvertáljuk. –static_cast (i) (Később) –char ch = i;

20 Kódelemzés #include 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; }

21 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

22 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!

23 Kódelemzés #include int main(int argc; char *argv[]) {... }

24 Kódelemzés #include void toupper(std::istream&, std::ostream&); int main( int argc; char *argv[] ) { if ( argc < 2 ) { toupper(std::cin, std::cout); }

25 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.

26 Kódelemzés #include void toupper(std::istream&, std::ostream&); int main( int argc; char *argv[]) { if ( argc < 2 ) { toupper(std::cin, std::cout); } else { // folyt. } return 0; }

27 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); }

28 Kódelemzés Kérdés: Kell-e close-t mondanom? –Amikor a zárójelet becsukom, akkor az ifstream destruktora meghívódik!

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

30 Kódelemzés #include void lines(std::istream&, std::ostream&); int main( int argc; char *argv[]) { if ( argc < 2 ) { lines(std::cin, std::cout); } else { // folyt. } return 0; }

31 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); }

32 Kódelemzés Egy adott karakter előfordulása egy egyszerű számlálás!

33 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; }

34 Kódelemzés int f( int cnt, char prev, char curr ) // warning! { if ( '\n' == prev ) { ++cnt; } return cnt; }

35 Kódelemzés int f( int cnt, char prev, char ) // így már nem! { if ( '\n' == prev ) { ++cnt; } return cnt; }

36 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; }

37 Kódelemzés Megoldás: #include 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; }

38 Kódelemzés Megoldás: más út #include 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; }

39 Kódelemzés Kimenet: alma szilva ctrl-D eredmény: 2 alma szilva ctrl-D eredmény: 1

40 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.

41 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; }

42 Kódelemzés Feladat: Szavak számának a számolása. alma (1) „ „ szilva (2) …

43 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; }

44 Kódelemzés Megoldás: Más út bool isWS(char c) { … }


Letölteni ppt "Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk D-2.620 1."

Hasonló előadás


Google Hirdetések